1 | #include <Common/Config/AbstractConfigurationComparison.h> |
2 | |
3 | #include <unordered_set> |
4 | #include <common/StringRef.h> |
5 | #include <Poco/Util/AbstractConfiguration.h> |
6 | |
7 | |
8 | namespace DB |
9 | { |
10 | namespace |
11 | { |
12 | String concatKeyAndSubKey(const String & key, const String & subkey) |
13 | { |
14 | // Copied from Poco::Util::ConfigurationView::translateKey(): |
15 | String result = key; |
16 | if (!result.empty() && !subkey.empty() && subkey[0] != '[') |
17 | result += '.'; |
18 | result += subkey; |
19 | return result; |
20 | }; |
21 | } |
22 | |
23 | |
24 | bool isSameConfiguration(const Poco::Util::AbstractConfiguration & left, const Poco::Util::AbstractConfiguration & right) |
25 | { |
26 | return isSameConfiguration(left, String(), right, String()); |
27 | } |
28 | |
29 | |
30 | bool isSameConfiguration(const Poco::Util::AbstractConfiguration & left, const String & left_key, |
31 | const Poco::Util::AbstractConfiguration & right, const String & right_key) |
32 | { |
33 | if (&left == &right && left_key == right_key) |
34 | return true; |
35 | |
36 | bool has_property = left.hasProperty(left_key); |
37 | if (has_property != right.hasProperty(right_key)) |
38 | return false; |
39 | if (has_property) |
40 | { |
41 | /// The left and right configurations contains values so we can compare them. |
42 | if (left.getRawString(left_key) != right.getRawString(right_key)) |
43 | return false; |
44 | } |
45 | |
46 | /// Get the subkeys of the left and right configurations. |
47 | Poco::Util::AbstractConfiguration::Keys subkeys; |
48 | left.keys(left_key, subkeys); |
49 | |
50 | { |
51 | /// Check that the right configuration has the same set of subkeys as the left configuration. |
52 | Poco::Util::AbstractConfiguration::Keys right_subkeys; |
53 | right.keys(right_key, right_subkeys); |
54 | std::unordered_set<StringRef> left_subkeys{subkeys.begin(), subkeys.end()}; |
55 | if ((left_subkeys.size() != right_subkeys.size()) || (left_subkeys.size() != subkeys.size())) |
56 | return false; |
57 | for (const auto & right_subkey : right_subkeys) |
58 | if (!left_subkeys.count(right_subkey)) |
59 | return false; |
60 | } |
61 | |
62 | /// Go through all the subkeys and compare corresponding parts of the configurations. |
63 | for (const auto & subkey : subkeys) |
64 | if (!isSameConfiguration(left, concatKeyAndSubKey(left_key, subkey), right, concatKeyAndSubKey(right_key, subkey))) |
65 | return false; |
66 | |
67 | return true; |
68 | } |
69 | |
70 | } |
71 | |