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();
/// 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();
template<typename T>
template<typename... ColumnTypes>
-T& Crud<T>::insert(ColumnTypes&&... cts)
+T& Crud<T>::insert(ColumnTypes&&... expression)
{
static_cast<T*>(this)->cache.clear();
- auto columnNames = static_cast<T*>(this)->getColumnNames(std::forward<ColumnTypes>(cts)...);
-
- std::stringstream ss;
- ss << "INSERT INTO " << static_cast<T*>(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<T*>(this)->name << " (";
+
+ auto onColumn = [&ss, this](const auto&... iter) {
+ (static_cast<void>( /// Make fold expression possible
+ (ss << static_cast<T*>(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<void>((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<T*>(this)->cache.emplace_back(ss.str());
+ static_cast<T*>(this)->cache.emplace_back(std::move(query));
return *(static_cast<T*>(this));
}
}
};
+template<typename L>
+struct Binary<L, std::string> : 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<typename L, typename R>
struct Greater : public Binary<L, R> {
using Binary<L, R>::Binary;
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)