Skip to content

Commit 4979e44

Browse files
committed
Prepare update query
1 parent afebee9 commit 4979e44

File tree

3 files changed

+174
-12
lines changed

3 files changed

+174
-12
lines changed

src/tests/test_update.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**********************************************************************************
2+
* MIT License
3+
*
4+
* Copyright (c) 2025-2026 Evgenii Sopov <mrseakg@gmail.com>
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
*all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*
24+
* Official Source Code: https://github.com/wsjcpp/wsjcpp-sql-builder
25+
*
26+
***********************************************************************************/
27+
28+
#include <iostream>
29+
#include <wsjcpp_sql_builder.h>
30+
31+
int main() {
32+
WsjcppSqlBuilder builder;
33+
builder.update("table3")
34+
.set("col1", "val uuu")
35+
.set("col2", 1)
36+
.set("col3", 1.000)
37+
.where()
38+
.equal("col1", "1")
39+
.or_()
40+
.notEqual("col2", "2")
41+
.or_()
42+
.subCondition()
43+
.equal("c3", "4")
44+
// .and_() // be default must be added and
45+
.equal("col2", "5")
46+
.finishSubCondition()
47+
.or_()
48+
.lessThen("col4", 111)
49+
;
50+
51+
if (builder.hasErrors()) {
52+
std::cerr << "Select builder has some errors" << std::endl;
53+
return -1;
54+
}
55+
std::string sqlQuery = builder.sql();
56+
std::string sqlQueryExpected = "UPDATE table3 SET col1 = 'val uuu', col2 = 1, col3 = 1.000000 WHERE col1 = '1' OR col2 <> '2' OR (c3 = '4' AND col2 = '5') OR col4 < 111";
57+
if (sqlQuery != sqlQueryExpected) {
58+
std::cerr
59+
<< "Expected:" << std::endl
60+
<< " {" << sqlQueryExpected << "}" << std::endl
61+
<< ", but got:" << std::endl
62+
<< " {" << sqlQuery << "}" << std::endl
63+
;
64+
return -1;
65+
}
66+
67+
return 0;
68+
}

src/wsjcpp_sql_builder.cpp

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@ WsjcppSqlWhere<WsjcppSqlSelect> &WsjcppSqlSelect::where() {
205205
if (!m_where) {
206206
m_where = std::make_shared<WsjcppSqlWhere<WsjcppSqlSelect>>(nullptr, builderRawPtr(), this);
207207
}
208-
209208
return *(m_where.get());
210209
}
211210

@@ -314,6 +313,70 @@ std::string WsjcppSqlInsert::sql() {
314313
return ret;
315314
};
316315

316+
// ---------------------------------------------------------------------
317+
// WsjcppSqlUpdate
318+
319+
WsjcppSqlUpdate::WsjcppSqlUpdate(const std::string &tableName, WsjcppSqlBuilder *builder)
320+
: WsjcppSqlQuery(WsjcppSqlQueryType::INSERT, builder, tableName) {
321+
322+
}
323+
324+
WsjcppSqlUpdate &WsjcppSqlUpdate::set(const std::string &name, const std::string &val) {
325+
return setValue(name, WsjcppSqlBuilderHelpers::escapingStringValue(val));
326+
}
327+
328+
WsjcppSqlUpdate &WsjcppSqlUpdate::set(const std::string &name, int val) {
329+
return setValue(name, std::to_string(val));
330+
}
331+
332+
WsjcppSqlUpdate &WsjcppSqlUpdate::set(const std::string &name, float val) {
333+
return setValue(name, std::to_string(val));
334+
}
335+
336+
WsjcppSqlUpdate &WsjcppSqlUpdate::set(const std::string &name, double val) {
337+
return setValue(name, std::to_string(val));
338+
}
339+
340+
WsjcppSqlUpdate &WsjcppSqlUpdate::setValue(const std::string &name, const std::string &val) {
341+
auto it = std::find(m_columns.begin(), m_columns.end(), name);
342+
if (it != m_columns.end()) {
343+
m_values[name] = val;
344+
// builder().addError("Column '" + name + "' already added to select");
345+
} else {
346+
m_columns.push_back(name);
347+
m_values[name] = val;
348+
}
349+
return *this;
350+
}
351+
352+
WsjcppSqlWhere<WsjcppSqlUpdate> &WsjcppSqlUpdate::where() {
353+
if (!m_where) {
354+
m_where = std::make_shared<WsjcppSqlWhere<WsjcppSqlUpdate>>(nullptr, builderRawPtr(), this);
355+
}
356+
return *(m_where.get());
357+
}
358+
359+
std::string WsjcppSqlUpdate::sql() {
360+
std::string ret = "UPDATE " + tableName() + " SET ";
361+
362+
// TODO if columns is empty
363+
bool first = true;
364+
for (auto col : m_columns) {
365+
if (!first) {
366+
ret += ", ";
367+
}
368+
ret += col + " = " + m_values[col];
369+
first = false;
370+
}
371+
372+
if (m_where) {
373+
ret += " WHERE " + m_where->sql();
374+
}
375+
376+
return ret;
377+
};
378+
379+
317380
// ---------------------------------------------------------------------
318381
// WsjcppSqlBuilder
319382

@@ -337,11 +400,19 @@ WsjcppSqlInsert &WsjcppSqlBuilder::findInsertOrCreate(const std::string &tableNa
337400
return insertInto(tableName);
338401
}
339402

340-
// WsjcppSqlBuilder &WsjcppSqlBuilder::makeUpdate(const std::string &tableName) {
341-
// m_tableName = tableName;
342-
// m_nSqlType = WsjcppSqlQueryType::UPDATE;
343-
// return *this;
344-
// }
403+
WsjcppSqlUpdate &WsjcppSqlBuilder::update(const std::string &tableName) {
404+
m_queries.push_back(std::make_shared<WsjcppSqlUpdate>(tableName, this));
405+
return *(WsjcppSqlUpdate *)(m_queries[m_queries.size() -1].get());
406+
}
407+
408+
WsjcppSqlUpdate &WsjcppSqlBuilder::findUpdateOrCreate(const std::string &tableName) {
409+
for (auto query : m_queries) {
410+
if (query->sqlType() == WsjcppSqlQueryType::UPDATE && query->tableName() == tableName) {
411+
return *(WsjcppSqlUpdate *)(query.get());
412+
}
413+
}
414+
return update(tableName);
415+
}
345416

346417
// WsjcppSqlBuilder &WsjcppSqlBuilder::makeDelete(const std::string &tableName) {
347418
// m_tableName = tableName;

src/wsjcpp_sql_builder.h

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -243,27 +243,48 @@ class WsjcppSqlInsert : public WsjcppSqlQuery {
243243
WsjcppSqlInsert &addColums(const std::vector<std::string> &cols);
244244
WsjcppSqlInsert &clearValues();
245245

246-
WsjcppSqlInsert &val(const std::string &col);
247-
WsjcppSqlInsert &val(int col);
248-
WsjcppSqlInsert &val(float col);
249-
WsjcppSqlInsert &val(double col);
246+
WsjcppSqlInsert &val(const std::string &val);
247+
WsjcppSqlInsert &val(int val);
248+
WsjcppSqlInsert &val(float val);
249+
WsjcppSqlInsert &val(double val);
250250

251-
WsjcppSqlBuilder &builder();
252251
virtual std::string sql() override;
253252

254253
private:
255254
std::vector<std::string> m_columns;
256255
std::vector<std::string> m_values;
257256
};
258257

258+
class WsjcppSqlUpdate : public WsjcppSqlQuery {
259+
public:
260+
WsjcppSqlUpdate(const std::string &tableName, WsjcppSqlBuilder *builder);
261+
262+
WsjcppSqlUpdate &set(const std::string &name, const std::string &val);
263+
WsjcppSqlUpdate &set(const std::string &name, int val);
264+
WsjcppSqlUpdate &set(const std::string &name, float val);
265+
WsjcppSqlUpdate &set(const std::string &name, double val);
266+
267+
WsjcppSqlWhere<WsjcppSqlUpdate> &where();
268+
269+
virtual std::string sql() override;
270+
271+
private:
272+
WsjcppSqlUpdate &setValue(const std::string &name, const std::string &val);
273+
274+
std::shared_ptr<WsjcppSqlWhere<WsjcppSqlUpdate>> m_where;
275+
std::vector<std::string> m_columns;
276+
std::map<std::string, std::string> m_values;
277+
};
278+
259279
class WsjcppSqlBuilder {
260280
public:
261281
// TODO begin / end transaction can be added here
262282

263283
WsjcppSqlSelect &selectFrom(const std::string &tableName);
264284
WsjcppSqlInsert &insertInto(const std::string &tableName);
265285
WsjcppSqlInsert &findInsertOrCreate(const std::string &tableName);
266-
// WsjcppSqlBuilder &update(const std::string &sSqlTable);
286+
WsjcppSqlUpdate &update(const std::string &tableName);
287+
WsjcppSqlUpdate &findUpdateOrCreate(const std::string &tableName);
267288
// WsjcppSqlBuilder &deleteFrom(const std::string &sSqlTable);
268289

269290
bool hasErrors();
@@ -272,6 +293,8 @@ class WsjcppSqlBuilder {
272293

273294
protected:
274295
friend WsjcppSqlSelect;
296+
friend WsjcppSqlInsert;
297+
friend WsjcppSqlUpdate;
275298
friend WsjcppSqlWhere<WsjcppSqlSelect>;
276299
void addError(const std::string &err);
277300

0 commit comments

Comments
 (0)