1#include "DictionaryFactory.h"
2
3#include <memory>
4#include "DictionarySourceFactory.h"
5#include "DictionaryStructure.h"
6#include "getDictionaryConfigurationFromAST.h"
7
8namespace DB
9{
10namespace ErrorCodes
11{
12 extern const int EXCESSIVE_ELEMENT_IN_CONFIG;
13 extern const int UNKNOWN_ELEMENT_IN_CONFIG;
14}
15
16void 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
26DictionaryPtr 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
58DictionaryPtr 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
64bool 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
75DictionaryFactory & DictionaryFactory::instance()
76{
77 static DictionaryFactory ret;
78 return ret;
79}
80
81}
82