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 | |