Skip to content

Commit 2b9f0d9

Browse files
committed
ql_template::Parser: Introduce 'CleanSections'
1 parent 72a1536 commit 2b9f0d9

File tree

3 files changed

+254
-50
lines changed

3 files changed

+254
-50
lines changed

src/oatpp-postgresql/ql_template/Parser.cpp

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@
2929

3030
namespace oatpp { namespace postgresql { namespace ql_template {
3131

32-
oatpp::String Parser::preprocess(const oatpp::String& text) {
32+
oatpp::String Parser::preprocess(const oatpp::String& text, std::vector<CleanSection>& cleanSections) {
3333

3434
data::stream::BufferOutputStream ss;
3535
parser::Caret caret(text);
3636

37-
bool ignore = false;
3837
bool writeChar = true;
3938

39+
v_buff_size sectionStart = -1;
40+
4041
while(caret.canContinue()) {
4142

4243
v_char8 c = *caret.getCurrData();
@@ -58,26 +59,32 @@ oatpp::String Parser::preprocess(const oatpp::String& text) {
5859
writeChar = false;
5960
break;
6061
}
62+
6163
case '<': {
62-
caret.inc();
63-
if(!ignore) {
64-
ignore = caret.canContinue() && caret.isAtChar('[');
65-
if(ignore) {
66-
caret.inc();
64+
if(sectionStart == -1) {
65+
if(caret.isAtText((p_char8) "<!!", 3, true)) {
66+
sectionStart = ss.getCurrentPosition();
6767
writeChar = false;
68+
} else {
69+
caret.inc();
6870
}
71+
} else {
72+
caret.inc();
6973
}
7074
break;
7175
}
7276

73-
case ']': {
74-
caret.inc();
75-
if(ignore) {
76-
ignore = !(caret.canContinue() && caret.isAtChar('>'));
77-
if(!ignore) {
78-
caret.inc();
77+
case '!': {
78+
if(sectionStart != -1) {
79+
if(caret.isAtText((p_char8) "!!>", 3, true)) {
80+
cleanSections.emplace_back(CleanSection(sectionStart, ss.getCurrentPosition() - sectionStart));
81+
sectionStart = -1;
7982
writeChar = false;
83+
} else {
84+
caret.inc();
8085
}
86+
} else {
87+
caret.inc();
8188
}
8289
break;
8390
}
@@ -88,11 +95,7 @@ oatpp::String Parser::preprocess(const oatpp::String& text) {
8895
}
8996

9097
if(writeChar) {
91-
if (ignore) {
92-
ss.writeCharSimple('_');
93-
} else {
94-
ss.writeCharSimple(c);
95-
}
98+
ss.writeCharSimple(c);
9699
}
97100

98101
}
@@ -172,11 +175,23 @@ void Parser::skipStringInDollars(parser::Caret& caret) {
172175

173176
data::share::StringTemplate Parser::parseTemplate(const oatpp::String& text) {
174177

178+
std::vector<CleanSection> cleanSections;
179+
auto processedText = preprocess(text, cleanSections);
180+
181+
parser::Caret caret(processedText);
182+
175183
std::vector<data::share::StringTemplate::Variable> variables;
176184

177-
parser::Caret caret(preprocess(text));
185+
v_buff_size currSection = 0;
186+
178187
while(caret.canContinue()) {
179188

189+
if(currSection < cleanSections.size() && cleanSections[currSection].position == caret.getPosition()) {
190+
caret.inc(cleanSections[currSection].size);
191+
currSection ++;
192+
continue;
193+
}
194+
180195
v_char8 c = *caret.getCurrData();
181196

182197
switch(c) {
@@ -203,7 +218,7 @@ data::share::StringTemplate Parser::parseTemplate(const oatpp::String& text) {
203218
throw oatpp::parser::ParsingError(caret.getErrorMessage(), caret.getErrorCode(), caret.getPosition());
204219
}
205220

206-
return data::share::StringTemplate(text, std::move(variables));
221+
return data::share::StringTemplate(processedText, std::move(variables));
207222

208223
}
209224

src/oatpp-postgresql/ql_template/Parser.hpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ class Parser {
6565

6666
};
6767

68+
public:
69+
70+
struct CleanSection {
71+
CleanSection(v_buff_size p, v_buff_size s)
72+
: position(p)
73+
, size(s)
74+
{}
75+
v_buff_size position;
76+
v_buff_size size;
77+
};
6878

6979
private:
7080
static data::share::StringTemplate::Variable parseIdentifier(parser::Caret& caret);
@@ -75,9 +85,10 @@ class Parser {
7585
/**
7686
* Preprocess text.
7787
* @param text
88+
* @param cleanSections - out vector of clean sections.
7889
* @return
7990
*/
80-
static oatpp::String preprocess(const oatpp::String& text);
91+
static oatpp::String preprocess(const oatpp::String& text, std::vector<CleanSection>& cleanSections);
8192

8293
/**
8394
* Parse query template.

test/oatpp-postgresql/ql_template/ParserTest.cpp

Lines changed: 207 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -36,49 +36,227 @@ typedef oatpp::postgresql::ql_template::Parser Parser;
3636

3737
void ParserTest::onRun() {
3838

39-
// {
40-
// oatpp::String text = "";
41-
// auto result = Parser::preprocess(text);
42-
// OATPP_ASSERT(result == text);
43-
// }
44-
//
45-
// {
46-
// oatpp::String text = "SELECT * FROM my_table;";
47-
// auto result = Parser::preprocess(text);
48-
// OATPP_ASSERT(result == text);
49-
// }
39+
{
40+
oatpp::String text = "";
41+
std::vector<Parser::CleanSection> sections;
42+
auto result = Parser::preprocess(text, sections);
43+
44+
OATPP_LOGD(TAG, "--- case ---");
45+
OATPP_LOGD(TAG, "sql='%s'", text->c_str());
46+
OATPP_LOGD(TAG, "res='%s'", result->c_str());
47+
48+
OATPP_ASSERT(result == text);
49+
50+
}
51+
52+
{
53+
oatpp::String text = "SELECT * FROM my_table;";
54+
std::vector<Parser::CleanSection> sections;
55+
auto result = Parser::preprocess(text, sections);
56+
57+
OATPP_LOGD(TAG, "--- case ---");
58+
OATPP_LOGD(TAG, "sql='%s'", text->c_str());
59+
OATPP_LOGD(TAG, "res='%s'", result->c_str());
60+
61+
OATPP_ASSERT(result == text);
62+
63+
}
64+
65+
{
66+
oatpp::String text = "SELECT <!! * !!> FROM my_table;";
67+
std::vector<Parser::CleanSection> sections;
68+
auto result = Parser::preprocess(text, sections);
69+
70+
OATPP_LOGD(TAG, "--- case ---");
71+
OATPP_LOGD(TAG, "sql='%s'", text->c_str());
72+
OATPP_LOGD(TAG, "res='%s'", result->c_str());
73+
74+
OATPP_ASSERT(sections.size() == 1);
75+
OATPP_ASSERT(result == "SELECT * FROM my_table;");
76+
{
77+
const auto& s = sections[0];
78+
OATPP_ASSERT(s.position == 7);
79+
OATPP_ASSERT(s.size == 3);
80+
}
81+
}
82+
83+
{
84+
oatpp::String text = "<!!SELECT * FROM my_table;!!>";
85+
std::vector<Parser::CleanSection> sections;
86+
auto result = Parser::preprocess(text, sections);
87+
88+
OATPP_LOGD(TAG, "--- case ---");
89+
OATPP_LOGD(TAG, "sql='%s'", text->c_str());
90+
OATPP_LOGD(TAG, "res='%s'", result->c_str());
91+
92+
OATPP_ASSERT(sections.size() == 1);
93+
OATPP_ASSERT(result == "SELECT * FROM my_table;");
94+
{
95+
const auto& s = sections[0];
96+
OATPP_ASSERT(s.position == 0);
97+
OATPP_ASSERT(s.size == result->getSize());
98+
}
99+
}
100+
101+
{
102+
oatpp::String text = "SELECT <!! * !!> FROM!!> my_table;";
103+
std::vector<Parser::CleanSection> sections;
104+
auto result = Parser::preprocess(text, sections);
105+
106+
OATPP_LOGD(TAG, "--- case ---");
107+
OATPP_LOGD(TAG, "sql='%s'", text->c_str());
108+
OATPP_LOGD(TAG, "res='%s'", result->c_str());
109+
110+
OATPP_ASSERT(sections.size() == 1);
111+
OATPP_ASSERT(result == "SELECT * FROM!!> my_table;");
112+
{
113+
const auto& s = sections[0];
114+
OATPP_ASSERT(s.position == 7);
115+
OATPP_ASSERT(s.size == 3);
116+
}
117+
}
118+
119+
{
120+
oatpp::String text = "SELECT <!! <!!* !!> FROM!!> my_table;";
121+
std::vector<Parser::CleanSection> sections;
122+
auto result = Parser::preprocess(text, sections);
123+
124+
OATPP_LOGD(TAG, "--- case ---");
125+
OATPP_LOGD(TAG, "sql='%s'", text->c_str());
126+
OATPP_LOGD(TAG, "res='%s'", result->c_str());
127+
128+
OATPP_ASSERT(sections.size() == 1);
129+
OATPP_ASSERT(result == "SELECT <!!* FROM!!> my_table;");
130+
{
131+
const auto& s = sections[0];
132+
OATPP_ASSERT(s.position == 7);
133+
OATPP_ASSERT(s.size == 6);
134+
}
135+
}
136+
137+
{
138+
oatpp::String text = "SELECT < !! * !! > FROM!!> my_table;";
139+
std::vector<Parser::CleanSection> sections;
140+
auto result = Parser::preprocess(text, sections);
141+
142+
OATPP_LOGD(TAG, "--- case ---");
143+
OATPP_LOGD(TAG, "sql='%s'", text->c_str());
144+
OATPP_LOGD(TAG, "res='%s'", result->c_str());
145+
146+
OATPP_ASSERT(sections.size() == 0);
147+
OATPP_ASSERT(result == text);
148+
}
50149

51150
{
52-
oatpp::String text = "SELECT <[ * ]> FROM my_table;";
53-
auto result = Parser::preprocess(text);
54-
OATPP_ASSERT(result == "SELECT ___ FROM my_table;");
151+
oatpp::String text = "SELECT <!! schedule[1:2][2] !!> FROM <!!my_table!!>;";
152+
std::vector<Parser::CleanSection> sections;
153+
auto result = Parser::preprocess(text, sections);
154+
155+
OATPP_LOGD(TAG, "--- case ---");
156+
OATPP_LOGD(TAG, "sql='%s'", text->c_str());
157+
OATPP_LOGD(TAG, "res='%s'", result->c_str());
158+
159+
OATPP_ASSERT(sections.size() == 2);
160+
OATPP_ASSERT(result == "SELECT schedule[1:2][2] FROM my_table;");
161+
162+
{
163+
const auto& s = sections[0];
164+
OATPP_ASSERT(s.position == 7);
165+
OATPP_ASSERT(s.size == 18);
166+
}
167+
168+
{
169+
const auto& s = sections[1];
170+
OATPP_ASSERT(s.position == 31);
171+
OATPP_ASSERT(s.size == 8);
172+
}
173+
174+
}
175+
176+
{
177+
oatpp::String text = "SELECT <!! * '!!>' FROM!!> my_table;";
178+
std::vector<Parser::CleanSection> sections;
179+
auto result = Parser::preprocess(text, sections);
180+
181+
OATPP_LOGD(TAG, "--- case ---");
182+
OATPP_LOGD(TAG, "sql='%s'", text->c_str());
183+
OATPP_LOGD(TAG, "res='%s'", result->c_str());
184+
185+
OATPP_ASSERT(sections.size() == 1);
186+
OATPP_ASSERT(result == "SELECT * '!!>' FROM my_table;");
187+
188+
{
189+
const auto& s = sections[0];
190+
OATPP_ASSERT(s.position == 7);
191+
OATPP_ASSERT(s.size == 13);
192+
}
193+
55194
}
56195

57196
{
58-
oatpp::String text = "<[SELECT * FROM my_table;]>";
59-
auto result = Parser::preprocess(text);
60-
OATPP_ASSERT(result == "_______________________");
197+
oatpp::String text = "SELECT '<!!' * <!! FROM!!> my_table;";
198+
std::vector<Parser::CleanSection> sections;
199+
auto result = Parser::preprocess(text, sections);
200+
201+
OATPP_LOGD(TAG, "--- case ---");
202+
OATPP_LOGD(TAG, "sql='%s'", text->c_str());
203+
OATPP_LOGD(TAG, "res='%s'", result->c_str());
204+
205+
OATPP_ASSERT(sections.size() == 1);
206+
OATPP_ASSERT(result == "SELECT '<!!' * FROM my_table;");
207+
208+
{
209+
const auto& s = sections[0];
210+
OATPP_ASSERT(s.position == 15);
211+
OATPP_ASSERT(s.size == 5);
212+
}
213+
61214
}
62215

63216
{
64-
oatpp::String text = "SELECT <[ * ]> FROM]> my_table;";
65-
auto result = Parser::preprocess(text);
66-
OATPP_LOGD(TAG, "sql='%s'", text->getData());
67-
OATPP_LOGD(TAG, "res='%s'", result->getData());
217+
oatpp::String text = "SELECT * <!!!!> FROM my_table;";
218+
std::vector<Parser::CleanSection> sections;
219+
auto result = Parser::preprocess(text, sections);
220+
221+
OATPP_LOGD(TAG, "--- case ---");
222+
OATPP_LOGD(TAG, "sql='%s'", text->c_str());
223+
OATPP_LOGD(TAG, "res='%s'", result->c_str());
224+
225+
OATPP_ASSERT(sections.size() == 1);
226+
OATPP_ASSERT(result == "SELECT * FROM my_table;");
227+
228+
{
229+
const auto& s = sections[0];
230+
OATPP_ASSERT(s.position == 9);
231+
OATPP_ASSERT(s.size == 0);
232+
}
233+
68234
}
69235

70236
{
71-
oatpp::String text = "SELECT < [ * ] > FROM]> my_table;";
72-
auto result = Parser::preprocess(text);
73-
OATPP_LOGD(TAG, "sql='%s'", text->getData());
74-
OATPP_LOGD(TAG, "res='%s'", result->getData());
237+
oatpp::String text = "SELECT <!! name::text !!> FROM my_table WHERE id=:id;";
238+
std::vector<Parser::CleanSection> sections;
239+
auto temp = Parser::parseTemplate(text);
240+
auto result = temp.format("<val>");
241+
242+
OATPP_LOGD(TAG, "--- case ---");
243+
OATPP_LOGD(TAG, "sql='%s'", text->c_str());
244+
OATPP_LOGD(TAG, "res='%s'", result->c_str());
245+
246+
OATPP_ASSERT(result == "SELECT name::text FROM my_table WHERE id=<val>;");
75247
}
76248

77249
{
78-
oatpp::String text = "SELECT <[ * ']>' FROM my_table;";
79-
auto result = Parser::preprocess(text);
80-
OATPP_LOGD(TAG, "sql='%s'", text->getData());
81-
OATPP_LOGD(TAG, "res='%s'", result->getData());
250+
oatpp::String text = "SELECT <!! name::text !!> FROM my_table WHERE <!! id=:id !!>;";
251+
std::vector<Parser::CleanSection> sections;
252+
auto temp = Parser::parseTemplate(text);
253+
auto result = temp.format("<val>");
254+
255+
OATPP_LOGD(TAG, "--- case ---");
256+
OATPP_LOGD(TAG, "sql='%s'", text->c_str());
257+
OATPP_LOGD(TAG, "res='%s'", result->c_str());
258+
259+
OATPP_ASSERT(result == "SELECT name::text FROM my_table WHERE id=:id ;");
82260
}
83261

84262
}

0 commit comments

Comments
 (0)