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
10namespace DB
11{
12
13namespace ErrorCodes
14{
15 extern const int THERE_IS_NO_PROFILE;
16 extern const int NO_ELEMENTS_IN_CONFIG;
17}
18
19
20IMPLEMENT_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 */
26void 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
47void 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
61void 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
100void 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