| 1 | #include "DictionaryFactory.h" |
| 2 | |
| 3 | #include <memory> |
| 4 | #include "DictionarySourceFactory.h" |
| 5 | #include "DictionaryStructure.h" |
| 6 | #include "getDictionaryConfigurationFromAST.h" |
| 7 | |
| 8 | namespace DB |
| 9 | { |
| 10 | namespace ErrorCodes |
| 11 | { |
| 12 | extern const int EXCESSIVE_ELEMENT_IN_CONFIG; |
| 13 | extern const int UNKNOWN_ELEMENT_IN_CONFIG; |
| 14 | } |
| 15 | |
| 16 | void DictionaryFactory::registerLayout(const std::string & layout_type, Creator create_layout, bool is_complex) |
| 17 | { |
| 18 | if (!registered_layouts.emplace(layout_type, std::move(create_layout)).second) |
| 19 | throw Exception("DictionaryFactory: the layout name '" + layout_type + "' is not unique" , ErrorCodes::LOGICAL_ERROR); |
| 20 | |
| 21 | layout_complexity[layout_type] = is_complex; |
| 22 | |
| 23 | } |
| 24 | |
| 25 | |
| 26 | DictionaryPtr DictionaryFactory::create( |
| 27 | const std::string & name, |
| 28 | const Poco::Util::AbstractConfiguration & config, |
| 29 | const std::string & config_prefix, |
| 30 | const Context & context, |
| 31 | bool check_source_config) const |
| 32 | { |
| 33 | Poco::Util::AbstractConfiguration::Keys keys; |
| 34 | const auto & layout_prefix = config_prefix + ".layout" ; |
| 35 | config.keys(layout_prefix, keys); |
| 36 | if (keys.size() != 1) |
| 37 | throw Exception{name + ": element dictionary.layout should have exactly one child element" , |
| 38 | ErrorCodes::EXCESSIVE_ELEMENT_IN_CONFIG}; |
| 39 | |
| 40 | const DictionaryStructure dict_struct{config, config_prefix + ".structure" }; |
| 41 | |
| 42 | DictionarySourcePtr source_ptr = DictionarySourceFactory::instance().create(name, config, config_prefix + ".source" , dict_struct, context, check_source_config); |
| 43 | |
| 44 | const auto & layout_type = keys.front(); |
| 45 | |
| 46 | { |
| 47 | const auto found = registered_layouts.find(layout_type); |
| 48 | if (found != registered_layouts.end()) |
| 49 | { |
| 50 | const auto & layout_creator = found->second; |
| 51 | return layout_creator(name, dict_struct, config, config_prefix, std::move(source_ptr)); |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | throw Exception{name + ": unknown dictionary layout type: " + layout_type, ErrorCodes::UNKNOWN_ELEMENT_IN_CONFIG}; |
| 56 | } |
| 57 | |
| 58 | DictionaryPtr DictionaryFactory::create(const std::string & name, const ASTCreateQuery & ast, const Context & context) const |
| 59 | { |
| 60 | auto configurationFromAST = getDictionaryConfigurationFromAST(ast); |
| 61 | return DictionaryFactory::create(name, *configurationFromAST, "dictionary" , context, true); |
| 62 | } |
| 63 | |
| 64 | bool DictionaryFactory::isComplex(const std::string & layout_type) const |
| 65 | { |
| 66 | auto found = layout_complexity.find(layout_type); |
| 67 | |
| 68 | if (found != layout_complexity.end()) |
| 69 | return found->second; |
| 70 | |
| 71 | throw Exception{"Unknown dictionary layout type: " + layout_type, ErrorCodes::UNKNOWN_ELEMENT_IN_CONFIG}; |
| 72 | } |
| 73 | |
| 74 | |
| 75 | DictionaryFactory & DictionaryFactory::instance() |
| 76 | { |
| 77 | static DictionaryFactory ret; |
| 78 | return ret; |
| 79 | } |
| 80 | |
| 81 | } |
| 82 | |