1 | #include "Settings.h" |
2 | |
3 | #include <Poco/Util/AbstractConfiguration.h> |
4 | #include <Columns/ColumnArray.h> |
5 | #include <Common/typeid_cast.h> |
6 | #include <string.h> |
7 | #include <boost/program_options/options_description.hpp> |
8 | #include <Core/SettingsCollectionImpl.h> |
9 | |
10 | namespace DB |
11 | { |
12 | |
13 | namespace ErrorCodes |
14 | { |
15 | extern const int THERE_IS_NO_PROFILE; |
16 | extern const int NO_ELEMENTS_IN_CONFIG; |
17 | } |
18 | |
19 | |
20 | IMPLEMENT_SETTINGS_COLLECTION(Settings, LIST_OF_SETTINGS) |
21 | |
22 | |
23 | /** Set the settings from the profile (in the server configuration, many settings can be listed in one profile). |
24 | * The profile can also be set using the `set` functions, like the `profile` setting. |
25 | */ |
26 | void Settings::setProfile(const String & profile_name, const Poco::Util::AbstractConfiguration & config) |
27 | { |
28 | String elem = "profiles." + profile_name; |
29 | |
30 | if (!config.has(elem)) |
31 | throw Exception("There is no profile '" + profile_name + "' in configuration file." , ErrorCodes::THERE_IS_NO_PROFILE); |
32 | |
33 | Poco::Util::AbstractConfiguration::Keys config_keys; |
34 | config.keys(elem, config_keys); |
35 | |
36 | for (const std::string & key : config_keys) |
37 | { |
38 | if (key == "constraints" ) |
39 | continue; |
40 | if (key == "profile" || 0 == key.compare(0, strlen("profile[" ), "profile[" )) /// Inheritance of profiles from the current one. |
41 | setProfile(config.getString(elem + "." + key), config); |
42 | else |
43 | set(key, config.getString(elem + "." + key)); |
44 | } |
45 | } |
46 | |
47 | void Settings::loadSettingsFromConfig(const String & path, const Poco::Util::AbstractConfiguration & config) |
48 | { |
49 | if (!config.has(path)) |
50 | throw Exception("There is no path '" + path + "' in configuration file." , ErrorCodes::NO_ELEMENTS_IN_CONFIG); |
51 | |
52 | Poco::Util::AbstractConfiguration::Keys config_keys; |
53 | config.keys(path, config_keys); |
54 | |
55 | for (const std::string & key : config_keys) |
56 | { |
57 | set(key, config.getString(path + "." + key)); |
58 | } |
59 | } |
60 | |
61 | void Settings::dumpToArrayColumns(IColumn * column_names_, IColumn * column_values_, bool changed_only) |
62 | { |
63 | /// Convert ptr and make simple check |
64 | auto column_names = (column_names_) ? &typeid_cast<ColumnArray &>(*column_names_) : nullptr; |
65 | auto column_values = (column_values_) ? &typeid_cast<ColumnArray &>(*column_values_) : nullptr; |
66 | |
67 | size_t size = 0; |
68 | |
69 | for (const auto & setting : *this) |
70 | { |
71 | if (!changed_only || setting.isChanged()) |
72 | { |
73 | if (column_names) |
74 | { |
75 | StringRef name = setting.getName(); |
76 | column_names->getData().insertData(name.data, name.size); |
77 | } |
78 | if (column_values) |
79 | column_values->getData().insert(setting.getValueAsString()); |
80 | ++size; |
81 | } |
82 | } |
83 | |
84 | if (column_names) |
85 | { |
86 | auto & offsets = column_names->getOffsets(); |
87 | offsets.push_back(offsets.back() + size); |
88 | } |
89 | |
90 | /// Nested columns case |
91 | bool the_same_offsets = column_names && column_values && column_names->getOffsetsPtr() == column_values->getOffsetsPtr(); |
92 | |
93 | if (column_values && !the_same_offsets) |
94 | { |
95 | auto & offsets = column_values->getOffsets(); |
96 | offsets.push_back(offsets.back() + size); |
97 | } |
98 | } |
99 | |
100 | void Settings::addProgramOptions(boost::program_options::options_description & options) |
101 | { |
102 | for (size_t index = 0; index != Settings::size(); ++index) |
103 | { |
104 | auto on_program_option |
105 | = boost::function1<void, const std::string &>([this, index](const std::string & value) { set(index, value); }); |
106 | options.add(boost::shared_ptr<boost::program_options::option_description>(new boost::program_options::option_description( |
107 | Settings::getName(index).data, |
108 | boost::program_options::value<std::string>()->composing()->notifier(on_program_option), |
109 | Settings::getDescription(index).data))); |
110 | } |
111 | } |
112 | } |
113 | |