1#pragma once
2
3#include <Common/SettingsChanges.h>
4#include <Core/Settings.h>
5
6namespace Poco
7{
8namespace Util
9{
10 class AbstractConfiguration;
11}
12}
13
14
15namespace DB
16{
17struct Settings;
18
19/** Checks if specified changes of settings are allowed or not.
20 * If the changes are not allowed (i.e. violates some constraints) this class throws an exception.
21 * The constraints are set by editing the `users.xml` file.
22 *
23 * For examples, the following lines in `users.xml` will set that `max_memory_usage` cannot be greater than 20000000000,
24 * and `force_index_by_date` should be always equal to 0:
25 *
26 * <profiles>
27 * <user_profile>
28 * <max_memory_usage>10000000000</max_memory_usage>
29 * <force_index_by_date>0</force_index_by_date>
30 * ...
31 * <constraints>
32 * <max_memory_usage>
33 * <min>200000</min>
34 * <max>20000000000</max>
35 * </max_memory_usage>
36 * <force_index_by_date>
37 * <readonly/>
38 * </force_index_by_date>
39 * </constraints>
40 * </user_profile>
41 * </profiles>
42 *
43 * This class also checks that we are not in the read-only mode.
44 * If a setting cannot be change due to the read-only mode this class throws an exception.
45 * The value of `readonly` value is understood as follows:
46 * 0 - everything allowed.
47 * 1 - only read queries can be made; you can not change the settings.
48 * 2 - you can only do read queries and you can change the settings, except for the `readonly` setting.
49 */
50class SettingsConstraints
51{
52public:
53 SettingsConstraints();
54 SettingsConstraints(const SettingsConstraints & src);
55 SettingsConstraints & operator =(const SettingsConstraints & src);
56 SettingsConstraints(SettingsConstraints && src);
57 SettingsConstraints & operator =(SettingsConstraints && src);
58 ~SettingsConstraints();
59
60 void clear();
61 bool empty() const { return constraints_by_index.empty(); }
62
63 void setMinValue(const StringRef & name, const Field & min_value);
64 Field getMinValue(const StringRef & name) const;
65
66 void setMaxValue(const StringRef & name, const Field & max_value);
67 Field getMaxValue(const StringRef & name) const;
68
69 void setReadOnly(const StringRef & name, bool read_only);
70 bool isReadOnly(const StringRef & name) const;
71
72 void set(const StringRef & name, const Field & min_value, const Field & max_value, bool read_only);
73 void get(const StringRef & name, Field & min_value, Field & max_value, bool & read_only) const;
74
75 void merge(const SettingsConstraints & other);
76
77 struct Info
78 {
79 StringRef name;
80 Field min;
81 Field max;
82 bool read_only = false;
83 };
84 using Infos = std::vector<Info>;
85
86 Infos getInfo() const;
87
88 void check(const Settings & current_settings, const SettingChange & change) const;
89 void check(const Settings & current_settings, const SettingsChanges & changes) const;
90
91 /** Set multiple settings from "profile" (in server configuration file (users.xml), profiles contain groups of multiple settings).
92 * The profile can also be set using the `set` functions, like the profile setting.
93 */
94 void setProfile(const String & profile_name, const Poco::Util::AbstractConfiguration & config);
95
96 /// Loads the constraints from configuration file, at "path" prefix in configuration.
97 void loadFromConfig(const String & path, const Poco::Util::AbstractConfiguration & config);
98
99 friend bool operator ==(const SettingsConstraints & lhs, const SettingsConstraints & rhs);
100 friend bool operator !=(const SettingsConstraints & lhs, const SettingsConstraints & rhs) { return !(lhs == rhs); }
101
102private:
103 struct Constraint
104 {
105 bool read_only = false;
106 Field min_value;
107 Field max_value;
108
109 bool operator ==(const Constraint & rhs) const;
110 bool operator !=(const Constraint & rhs) const { return !(*this == rhs); }
111 };
112
113 Constraint & getConstraintRef(size_t index);
114 const Constraint * tryGetConstraint(size_t) const;
115
116 std::unordered_map<size_t, Constraint> constraints_by_index;
117};
118
119}
120