| 1 | //===----------------------------------------------------------------------===// |
| 2 | // DuckDB |
| 3 | // |
| 4 | // duckdb/main/extension_helper.hpp |
| 5 | // |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #pragma once |
| 10 | |
| 11 | #include <string> |
| 12 | #include "duckdb.hpp" |
| 13 | |
| 14 | namespace duckdb { |
| 15 | class DuckDB; |
| 16 | |
| 17 | enum class ExtensionLoadResult : uint8_t { LOADED_EXTENSION = 0, EXTENSION_UNKNOWN = 1, NOT_LOADED = 2 }; |
| 18 | |
| 19 | struct DefaultExtension { |
| 20 | const char *name; |
| 21 | const char *description; |
| 22 | bool statically_loaded; |
| 23 | }; |
| 24 | |
| 25 | struct ExtensionAlias { |
| 26 | const char *alias; |
| 27 | const char *extension; |
| 28 | }; |
| 29 | |
| 30 | struct ExtensionInitResult { |
| 31 | string filename; |
| 32 | string basename; |
| 33 | |
| 34 | void *lib_hdl; |
| 35 | }; |
| 36 | |
| 37 | class ExtensionHelper { |
| 38 | public: |
| 39 | static void LoadAllExtensions(DuckDB &db); |
| 40 | |
| 41 | static ExtensionLoadResult LoadExtension(DuckDB &db, const std::string &extension); |
| 42 | |
| 43 | static void InstallExtension(ClientContext &context, const string &extension, bool force_install); |
| 44 | static void InstallExtension(DBConfig &config, FileSystem &fs, const string &extension, bool force_install); |
| 45 | static void LoadExternalExtension(ClientContext &context, const string &extension); |
| 46 | static void LoadExternalExtension(DatabaseInstance &db, FileSystem &fs, const string &extension); |
| 47 | |
| 48 | static string ExtensionDirectory(ClientContext &context); |
| 49 | static string ExtensionDirectory(DBConfig &config, FileSystem &fs); |
| 50 | |
| 51 | static idx_t DefaultExtensionCount(); |
| 52 | static DefaultExtension GetDefaultExtension(idx_t index); |
| 53 | |
| 54 | static idx_t ExtensionAliasCount(); |
| 55 | static ExtensionAlias GetExtensionAlias(idx_t index); |
| 56 | |
| 57 | static const vector<string> GetPublicKeys(); |
| 58 | |
| 59 | // Returns extension name, or empty string if not a replacement open path |
| 60 | static string (const string &path); |
| 61 | |
| 62 | //! Apply any known extension aliases |
| 63 | static string ApplyExtensionAlias(string extension_name); |
| 64 | |
| 65 | static string GetExtensionName(const string &extension); |
| 66 | static bool IsFullPath(const string &extension); |
| 67 | |
| 68 | private: |
| 69 | static void InstallExtensionInternal(DBConfig &config, ClientConfig *client_config, FileSystem &fs, |
| 70 | const string &local_path, const string &extension, bool force_install); |
| 71 | static const vector<string> PathComponents(); |
| 72 | static bool AllowAutoInstall(const string &extension); |
| 73 | static ExtensionInitResult InitialLoad(DBConfig &config, FileSystem &fs, const string &extension); |
| 74 | static bool TryInitialLoad(DBConfig &config, FileSystem &fs, const string &extension, ExtensionInitResult &result, |
| 75 | string &error); |
| 76 | //! For tagged releases we use the tag, else we use the git commit hash |
| 77 | static const string GetVersionDirectoryName(); |
| 78 | //! Version tags occur with and without 'v', tag in extension path is always with 'v' |
| 79 | static const string NormalizeVersionTag(const string &version_tag); |
| 80 | static bool IsRelease(const string &version_tag); |
| 81 | static bool CreateSuggestions(const string &extension_name, string &message); |
| 82 | |
| 83 | private: |
| 84 | static ExtensionLoadResult LoadExtensionInternal(DuckDB &db, const std::string &extension, bool initial_load); |
| 85 | }; |
| 86 | |
| 87 | } // namespace duckdb |
| 88 | |