| 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 | |