1#include "applySubstitutions.h"
2#include <algorithm>
3#include <vector>
4
5namespace DB
6{
7
8void 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
33static 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
70Strings 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