1 | #include "applySubstitutions.h" |
2 | #include <algorithm> |
3 | #include <vector> |
4 | |
5 | namespace DB |
6 | { |
7 | |
8 | void constructSubstitutions(ConfigurationPtr & substitutions_view, StringToVector & out_substitutions) |
9 | { |
10 | Strings xml_substitutions; |
11 | substitutions_view->keys(xml_substitutions); |
12 | |
13 | for (size_t i = 0; i != xml_substitutions.size(); ++i) |
14 | { |
15 | const ConfigurationPtr xml_substitution(substitutions_view->createView("substitution[" + std::to_string(i) + "]" )); |
16 | |
17 | /// Property values for substitution will be stored in a vector |
18 | /// accessible by property name |
19 | Strings xml_values; |
20 | xml_substitution->keys("values" , xml_values); |
21 | |
22 | std::string name = xml_substitution->getString("name" ); |
23 | |
24 | for (size_t j = 0; j != xml_values.size(); ++j) |
25 | { |
26 | out_substitutions[name].push_back(xml_substitution->getString("values.value[" + std::to_string(j) + "]" )); |
27 | } |
28 | } |
29 | } |
30 | |
31 | /// Recursive method which goes through all substitution blocks in xml |
32 | /// and replaces property {names} by their values |
33 | static void runThroughAllOptionsAndPush(StringToVector::iterator substitutions_left, |
34 | StringToVector::iterator substitutions_right, |
35 | const std::string & template_query, |
36 | Strings & out_queries) |
37 | { |
38 | if (substitutions_left == substitutions_right) |
39 | { |
40 | out_queries.push_back(template_query); /// completely substituted query |
41 | return; |
42 | } |
43 | |
44 | std::string substitution_mask = "{" + substitutions_left->first + "}" ; |
45 | |
46 | if (template_query.find(substitution_mask) == std::string::npos) /// nothing to substitute here |
47 | { |
48 | runThroughAllOptionsAndPush(std::next(substitutions_left), substitutions_right, template_query, out_queries); |
49 | return; |
50 | } |
51 | |
52 | for (const std::string & value : substitutions_left->second) |
53 | { |
54 | /// Copy query string for each unique permutation |
55 | std::string query = template_query; |
56 | size_t substr_pos = 0; |
57 | |
58 | while (substr_pos != std::string::npos) |
59 | { |
60 | substr_pos = query.find(substitution_mask); |
61 | |
62 | if (substr_pos != std::string::npos) |
63 | query.replace(substr_pos, substitution_mask.length(), value); |
64 | } |
65 | |
66 | runThroughAllOptionsAndPush(std::next(substitutions_left), substitutions_right, query, out_queries); |
67 | } |
68 | } |
69 | |
70 | Strings formatQueries(const std::string & query, StringToVector substitutions_to_generate) |
71 | { |
72 | Strings queries_res; |
73 | runThroughAllOptionsAndPush( |
74 | substitutions_to_generate.begin(), |
75 | substitutions_to_generate.end(), |
76 | query, |
77 | queries_res); |
78 | return queries_res; |
79 | } |
80 | |
81 | |
82 | } |
83 | |