Skip to content

Commit 303bf83

Browse files
committed
Added support different data types for where conditions
1 parent aee4fda commit 303bf83

File tree

3 files changed

+85
-45
lines changed

3 files changed

+85
-45
lines changed

src/tests/test_select.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ int main() {
4646
.equal("col2", "5")
4747
.finishSubCondition()
4848
.or_()
49-
.lessThen("col4", "...")
49+
.lessThen("col4", 111)
5050
.endWhere() // need only for groupBy havingBy and etc
5151
;
5252
if (builder.hasErrors()) {
@@ -56,7 +56,7 @@ int main() {
5656
std::string sqlQueryExpected =
5757
"SELECT col1, col2 AS c3, col3, col4 "
5858
"FROM table1 "
59-
"WHERE col1 = \"1\" OR col2 <> \"2\" OR (c3 = \"4\" AND col2 = \"5\") OR col4 < \"...\"";
59+
"WHERE col1 = '1' OR col2 <> '2' OR (c3 = '4' AND col2 = '5') OR col4 < 111";
6060
if (sqlQuery != sqlQueryExpected) {
6161
std::cerr
6262
<< "Expected:" << std::endl

src/wsjcpp_sql_builder.cpp

Lines changed: 65 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,40 @@
2828
#include "wsjcpp_sql_builder.h"
2929
#include <algorithm>
3030

31+
32+
// ---------------------------------------------------------------------
33+
// WsjcppSqlBuilderHelpers
34+
35+
std::string WsjcppSqlBuilderHelpers::escapingStringValue(const std::string &sValue) {
36+
// escaping simbols NUL (ASCII 0), \n, \r, \, ', ", и Control-Z.
37+
std::string sResult;
38+
sResult.reserve(sValue.size() * 2);
39+
sResult.push_back('\'');
40+
for (int i = 0; i < sValue.size(); i++) {
41+
char c = sValue[i];
42+
if (c == '\n') {
43+
sResult.push_back('\\');
44+
sResult.push_back('n');
45+
} else if (c == '\r') {
46+
sResult.push_back('\\');
47+
sResult.push_back('r');
48+
} else if (c == '\\' || c == '"') {
49+
sResult.push_back('\\');
50+
sResult.push_back(c);
51+
} else if (c == '\'') {
52+
sResult.push_back('\'');
53+
sResult.push_back(c);
54+
} else if (c == 0) {
55+
sResult.push_back('\\');
56+
sResult.push_back('0');
57+
} else {
58+
sResult.push_back(c);
59+
}
60+
}
61+
sResult.push_back('\'');
62+
return sResult;
63+
}
64+
3165
// ---------------------------------------------------------------------
3266
// WsjcppSqlQuery
3367

@@ -71,9 +105,9 @@ bool WsjcppSqlQuery::add(const std::string &sColumnName,
71105
m_bValid = false;
72106
} else if (m_nSqlType == WsjcppSqlBuilderType::INSERT) {
73107
m_sSqlQuery0 += sColumnName + ", ";
74-
m_sSqlQuery1 += prepareStringValue(sValue) + ", ";
108+
m_sSqlQuery1 += WsjcppSqlBuilderHelpers::escapingStringValue(sValue) + ", ";
75109
} else if (m_nSqlType == WsjcppSqlBuilderType::UPDATE) {
76-
m_sSqlQuery0 += sColumnName + " = " + prepareStringValue(sValue);
110+
m_sSqlQuery0 += sColumnName + " = " + WsjcppSqlBuilderHelpers::escapingStringValue(sValue);
77111
} else {
78112
m_sErrorMessage = "Unknown sql type";
79113
m_bValid = false;
@@ -138,12 +172,12 @@ bool WsjcppSqlQuery::where(const std::string &sColumnName,
138172
return false;
139173
}
140174
if (m_nSqlType == WsjcppSqlBuilderType::SELECT) {
141-
m_sSqlQuery2 += sColumnName + " = " + prepareStringValue(sValue);
175+
m_sSqlQuery2 += sColumnName + " = " + WsjcppSqlBuilderHelpers::escapingStringValue(sValue);
142176
} else if (m_nSqlType == WsjcppSqlBuilderType::INSERT) {
143177
m_sErrorMessage = "where can be in insert";
144178
return false;
145179
} else if (m_nSqlType == WsjcppSqlBuilderType::UPDATE) {
146-
m_sSqlQuery1 += sColumnName + " = " + prepareStringValue(sValue);
180+
m_sSqlQuery1 += sColumnName + " = " + WsjcppSqlBuilderHelpers::escapingStringValue(sValue);
147181
}
148182

149183
return true;
@@ -239,36 +273,6 @@ bool WsjcppSqlQuery::checkName(const std::string &sColumnName) {
239273
return true;
240274
}
241275

242-
std::string WsjcppSqlQuery::prepareStringValue(const std::string &sValue) {
243-
// escaping simbols NUL (ASCII 0), \n, \r, \, ', ", и Control-Z.
244-
std::string sResult;
245-
sResult.reserve(sValue.size() * 2);
246-
sResult.push_back('\'');
247-
for (int i = 0; i < sValue.size(); i++) {
248-
char c = sValue[i];
249-
if (c == '\n') {
250-
sResult.push_back('\\');
251-
sResult.push_back('n');
252-
} else if (c == '\r') {
253-
sResult.push_back('\\');
254-
sResult.push_back('r');
255-
} else if (c == '\\' || c == '"') {
256-
sResult.push_back('\\');
257-
sResult.push_back(c);
258-
} else if (c == '\'') {
259-
sResult.push_back('\'');
260-
sResult.push_back(c);
261-
} else if (c == 0) {
262-
sResult.push_back('\\');
263-
sResult.push_back('0');
264-
} else {
265-
sResult.push_back(c);
266-
}
267-
}
268-
sResult.push_back('\'');
269-
return sResult;
270-
}
271-
272276
// ---------------------------------------------------------------------
273277
// WsjcppSqlBuilderSelect
274278

@@ -318,9 +322,33 @@ WsjcppSqlWhereCondition::WsjcppSqlWhereCondition(
318322
const std::string &name,
319323
WsjcppSqlWhereConditionType comparator,
320324
const std::string &value
321-
)
322-
: WsjcppSqlWhereBase(WsjcppSqlWhereType::CONDITION), m_name(name), m_comparator(comparator), m_value(value) {
325+
) : WsjcppSqlWhereBase(WsjcppSqlWhereType::CONDITION), m_name(name), m_comparator(comparator) {
326+
// TODO in different databases different quotes, mssql have a column names in double quotes
327+
m_value = WsjcppSqlBuilderHelpers::escapingStringValue(value);
328+
}
329+
330+
WsjcppSqlWhereCondition::WsjcppSqlWhereCondition(
331+
const std::string &name,
332+
WsjcppSqlWhereConditionType comparator,
333+
int value
334+
) : WsjcppSqlWhereBase(WsjcppSqlWhereType::CONDITION), m_name(name), m_comparator(comparator) {
335+
m_value = std::to_string(value);
336+
}
323337

338+
WsjcppSqlWhereCondition::WsjcppSqlWhereCondition(
339+
const std::string &name,
340+
WsjcppSqlWhereConditionType comparator,
341+
double value
342+
) : WsjcppSqlWhereBase(WsjcppSqlWhereType::CONDITION), m_name(name), m_comparator(comparator) {
343+
m_value = std::to_string(value);
344+
}
345+
346+
WsjcppSqlWhereCondition::WsjcppSqlWhereCondition(
347+
const std::string &name,
348+
WsjcppSqlWhereConditionType comparator,
349+
float value
350+
) : WsjcppSqlWhereBase(WsjcppSqlWhereType::CONDITION), m_name(name), m_comparator(comparator) {
351+
m_value = std::to_string(value);
324352
}
325353

326354
const std::string &WsjcppSqlWhereCondition::name() {
@@ -358,7 +386,7 @@ std::string WsjcppSqlWhereCondition::sql() {
358386
ret += " unknwon_operator ";
359387
break;
360388
}
361-
ret += "\"" + m_value + "\""; // TODO validate and escaping
389+
ret += m_value;
362390
return ret;
363391
}
364392

src/wsjcpp_sql_builder.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232
#include <vector>
3333
#include <memory>
3434

35+
class WsjcppSqlBuilderHelpers {
36+
public:
37+
static std::string escapingStringValue(const std::string &sValue);
38+
};
39+
3540

3641

3742
enum class WsjcppSqlBuilderType { SELECT, INSERT, UPDATE, DELETE };
@@ -54,7 +59,6 @@ class WsjcppSqlQuery {
5459
virtual std::string sql() { return ""; }; // TODO = 0;
5560

5661
private:
57-
std::string prepareStringValue(const std::string &sValue);
5862
bool checkName(const std::string &sColumnName);
5963
WsjcppSqlBuilderType m_nSqlType;
6064
std::string m_sSqlTable;
@@ -115,6 +119,9 @@ enum class WsjcppSqlWhereConditionType { NOT_EQUAL, EQUAL, MORE_THEN, LESS_THEN,
115119
class WsjcppSqlWhereCondition : public WsjcppSqlWhereBase {
116120
public:
117121
WsjcppSqlWhereCondition(const std::string &name, WsjcppSqlWhereConditionType comparator, const std::string &value);
122+
WsjcppSqlWhereCondition(const std::string &name, WsjcppSqlWhereConditionType comparator, int value);
123+
WsjcppSqlWhereCondition(const std::string &name, WsjcppSqlWhereConditionType comparator, double value);
124+
WsjcppSqlWhereCondition(const std::string &name, WsjcppSqlWhereConditionType comparator, float value);
118125
const std::string &name();
119126
WsjcppSqlWhereConditionType comparator();
120127
const std::string &value();
@@ -133,22 +140,26 @@ class WsjcppSqlWhere : public WsjcppSqlWhereBase {
133140
WsjcppSqlWhere(WsjcppSqlWhere<T> *parent, WsjcppSqlBuilder2 *builder, T *query)
134141
: WsjcppSqlWhereBase(WsjcppSqlWhereType::SUB_CONDITION), m_parent(parent), m_builder(builder), m_query(query) { }
135142

136-
WsjcppSqlWhere<T> &notEqual(const std::string &name, const std::string &value) {
143+
template <typename TVal>
144+
WsjcppSqlWhere<T> &notEqual(const std::string &name, TVal value) {
137145
cond(name, WsjcppSqlWhereConditionType::NOT_EQUAL, value);
138146
return *this;
139147
}
140148

141-
WsjcppSqlWhere<T> &equal(const std::string &name, const std::string &value) {
149+
template <typename TVal>
150+
WsjcppSqlWhere<T> &equal(const std::string &name, TVal value) {
142151
cond(name, WsjcppSqlWhereConditionType::EQUAL, value);
143152
return *this;
144153
}
145154

146-
WsjcppSqlWhere<T> &moreThen(const std::string &name, const std::string &value) {
155+
template <typename TVal>
156+
WsjcppSqlWhere<T> &moreThen(const std::string &name, TVal value) {
147157
cond(name, WsjcppSqlWhereConditionType::MORE_THEN, value);
148158
return *this;
149159
}
150160

151-
WsjcppSqlWhere<T> &lessThen(const std::string &name, const std::string &value) {
161+
template <typename TVal>
162+
WsjcppSqlWhere<T> &lessThen(const std::string &name, TVal value) {
152163
cond(name, WsjcppSqlWhereConditionType::LESS_THEN, value);
153164
return *this;
154165
}
@@ -224,7 +235,8 @@ class WsjcppSqlWhere : public WsjcppSqlWhereBase {
224235
}
225236

226237
private:
227-
WsjcppSqlWhere<T> &cond(const std::string &name, WsjcppSqlWhereConditionType comparator, const std::string &value) {
238+
template <typename TVal>
239+
WsjcppSqlWhere<T> &cond(const std::string &name, WsjcppSqlWhereConditionType comparator, TVal value) {
228240
if (
229241
m_conditions.size() > 0
230242
&& m_conditions[m_conditions.size()-1]->type() == WsjcppSqlWhereType::CONDITION

0 commit comments

Comments
 (0)