From bcc0bd8d602024d2088601edcc4116dc983adfc5 Mon Sep 17 00:00:00 2001 From: Sangwan Kwon Date: Tue, 18 Feb 2020 13:30:19 +0900 Subject: [PATCH] query-builder: Bind operand to insert clause ex) AdminTable.insert(Admin::Id = id, Admin::Pkg = "pkg", Admin::Key = "key"); - Before: "INSERT INTO admin (id, pkg, key) VALUES (?, ?, ?)" - Afater: "INSERT INTO admin (id, pkg, key) VALUES (0, 'pkg', 'key')" Signed-off-by: Sangwan Kwon --- src/vist/policy/policy-storage.cpp | 12 ++--- src/vist/query-builder/crud.hpp | 49 ++++++++++++------- src/vist/query-builder/expression.hpp | 13 +++++ .../query-builder/tests/query-builder.cpp | 22 +++++++-- 4 files changed, 66 insertions(+), 30 deletions(-) diff --git a/src/vist/policy/policy-storage.cpp b/src/vist/policy/policy-storage.cpp index e4f4f4a..3a3dcb7 100644 --- a/src/vist/policy/policy-storage.cpp +++ b/src/vist/policy/policy-storage.cpp @@ -124,11 +124,10 @@ void PolicyStorage::define(const std::string& policy, const PolicyValue& ivalue) PolicyDefinition pd = { policy, ivalue.dump() }; - std::string query = schema::PolicyDefinitionTable.insert(PolicyDefinition::Name, - PolicyDefinition::Ivalue); + std::string query = + schema::PolicyDefinitionTable.insert(PolicyDefinition::Name = pd.name, + PolicyDefinition::Ivalue = pd.ivalue); database::Statement stmt(*database, query); - stmt.bind(1, pd.name); - stmt.bind(2, pd.ivalue); if (!stmt.exec()) THROW(ErrCode::RuntimeError) << stmt.getErrorMessage(); @@ -147,10 +146,9 @@ void PolicyStorage::enroll(const std::string& name) /// Make admin deactivated as default. Admin admin = {name , 0}; - std::string query = schema::AdminTable.insert(Admin::Name, Admin::Activated); + std::string query = schema::AdminTable.insert(Admin::Name = admin.name, + Admin::Activated = admin.activated); database::Statement stmt(*database, query); - stmt.bind(1, admin.name); - stmt.bind(2, admin.activated); if (!stmt.exec()) THROW(ErrCode::RuntimeError) << stmt.getErrorMessage(); diff --git a/src/vist/query-builder/crud.hpp b/src/vist/query-builder/crud.hpp index cfdc2a0..3895aca 100644 --- a/src/vist/query-builder/crud.hpp +++ b/src/vist/query-builder/crud.hpp @@ -153,33 +153,46 @@ T& Crud::update(AssginExpressions&&... expression) template template -T& Crud::insert(ColumnTypes&&... cts) +T& Crud::insert(ColumnTypes&&... expression) { static_cast(this)->cache.clear(); - auto columnNames = static_cast(this)->getColumnNames(std::forward(cts)...); - - std::stringstream ss; - ss << "INSERT INTO " << static_cast(this)->name << " ("; - - const int columnCount = columnNames.size(); - for (int i = 0; i < columnCount; i++) { - ss << columnNames[i]; - if (i < columnCount - 1) - ss << ", "; + std::string query; + { + std::stringstream ss; + ss << "INSERT INTO " << static_cast(this)->name << " ("; + + auto onColumn = [&ss, this](const auto&... iter) { + (static_cast( /// Make fold expression possible + (ss << static_cast(this)->getColumnName(iter.l) << ", ") /// Column name + ), ...); /// Process fold expression + }; + std::apply(onColumn, std::tuple(expression...)); + + /// Remove last ", " + query = ss.str(); + if (query.size() > 2) + query.erase(query.end() - 2, query.end()); } - ss << ") VALUES ("; + query += ") VALUES ("; - for (int i = 0; i < columnCount; i++) { - ss << "?"; - if (i < columnCount - 1) - ss << ", "; + { + std::stringstream ss; + auto onValue = [&ss](const auto&... iter) { + (static_cast((ss << iter.r) << ", "), ...); /// Process fold expression + }; + std::apply(onValue, std::tuple(expression...)); + + /// Remove last ", " + query += ss.str(); + if (query.size() > 2) + query.erase(query.end() - 2, query.end()); } - ss << ")"; + query += ")"; - static_cast(this)->cache.emplace_back(ss.str()); + static_cast(this)->cache.emplace_back(std::move(query)); return *(static_cast(this)); } diff --git a/src/vist/query-builder/expression.hpp b/src/vist/query-builder/expression.hpp index fccf73e..eb6526d 100644 --- a/src/vist/query-builder/expression.hpp +++ b/src/vist/query-builder/expression.hpp @@ -60,6 +60,19 @@ struct Binary : public Expression { } }; +template +struct Binary : public Expression { + L l; + std::string r; + + /// Make r to 'r' + Binary(L l, std::string r) : l(l), r("'" + r + "'") + { + using FieldType = typename L::FieldType; + type::assert_compare(FieldType(), std::string()); + } +}; + template struct Greater : public Binary { using Binary::Binary; diff --git a/src/vist/query-builder/tests/query-builder.cpp b/src/vist/query-builder/tests/query-builder.cpp index c1765bb..c783acc 100644 --- a/src/vist/query-builder/tests/query-builder.cpp +++ b/src/vist/query-builder/tests/query-builder.cpp @@ -148,11 +148,23 @@ TEST(QueryBuilderTsqbTests, DELETE) TEST(QueryBuilderTsqbTests, INSERT) { - std::string insert1 = AdminTable.insert(Admin::Id, Admin::Pkg, Admin::Uid, Admin::Key); - std::string insert2 = AdminTable.insert(Admin::Id, Admin::Pkg, Admin::Key); - - EXPECT_EQ(insert1, "INSERT INTO admin (id, pkg, uid, key) VALUES (?, ?, ?, ?)"); - EXPECT_EQ(insert2, "INSERT INTO admin (id, pkg, key) VALUES (?, ?, ?)"); + int id = 0; + std::string pkg = "pkg"; + int uid = 1; + std::string key = "key"; + + std::string insert1 = AdminTable.insert(Admin::Id = id, + Admin::Pkg = pkg, + Admin::Uid = uid, + Admin::Key = key); + std::string insert2 = AdminTable.insert(Admin::Id = id, + Admin::Pkg = pkg, + Admin::Key = key); + + EXPECT_EQ(insert1, "INSERT INTO admin (id, pkg, uid, key) " + "VALUES (0, 'pkg', 1, 'key')"); + EXPECT_EQ(insert2, "INSERT INTO admin (id, pkg, key) " + "VALUES (0, 'pkg', 'key')"); } TEST(QueryBuilderTsqbTests, TYPE_SAFE) -- 2.34.1