From 96af55d8d0b8566997f0d756ceba66a3f9ed110f Mon Sep 17 00:00:00 2001 From: Jacyking <791026912@qq.com> Date: Wed, 13 Dec 2023 21:01:53 +0800 Subject: [PATCH 1/9] add update&replace api --- include/dbng.hpp | 10 ++++ include/mysql.hpp | 91 ++++++++++++++++++++++------- include/postgresql.hpp | 119 +++++++++++++++++++------------------ include/sqlite.hpp | 94 ++++++++++++++++++++++------- include/utility.hpp | 130 ++++++++++++++++++++++++++++++++++++++--- 5 files changed, 332 insertions(+), 112 deletions(-) diff --git a/include/dbng.hpp b/include/dbng.hpp index ce1487c4..3f0c5193 100644 --- a/include/dbng.hpp +++ b/include/dbng.hpp @@ -54,6 +54,16 @@ class dbng { return db_.update(t, std::forward(args)...); } + template + int replace(const T &t, Args &&...args) { + return db_.replace(t, std::forward(args)...); + } + + template + int replace(const std::vector &t, Args &&...args) { + return db_.replace(t, std::forward(args)...); + } + template bool delete_records(Args &&...where_conditon) { return db_.template delete_records( diff --git a/include/mysql.hpp b/include/mysql.hpp index 387dab94..7f800bad 100644 --- a/include/mysql.hpp +++ b/include/mysql.hpp @@ -100,23 +100,35 @@ class mysql { template int insert(const T &t, bool get_insert_id = false, Args &&...args) { - return insert_impl(false, t, get_insert_id, std::forward(args)...); + return insert_impl(OptType::insert, t, get_insert_id, + std::forward(args)...); } template int insert(const std::vector &t, bool get_insert_id = false, Args &&...args) { - return insert_impl(false, t, get_insert_id, std::forward(args)...); + return insert_impl(OptType::insert, t, get_insert_id, + std::forward(args)...); + } + + template + int replace(const T &t, Args &&...args) { + return insert_impl(OptType::replace, t, false, std::forward(args)...); + } + + template + int replace(const std::vector &t, Args &&...args) { + return insert_impl(OptType::replace, t, false, std::forward(args)...); } template int update(const T &t, Args &&...args) { - return insert_impl(true, t, false, std::forward(args)...); + return update_impl(t, std::forward(args)...); } template int update(const std::vector &t, Args &&...args) { - return insert_impl(true, t, false, std::forward(args)...); + return update_impl(t, std::forward(args)...); } template @@ -617,18 +629,25 @@ class mysql { } template - int stmt_execute(bool update, const T &t) { - reset_error(); + int stmt_execute(OptType type, const T &t) { std::vector param_binds; - - iguana::for_each(t, [&t, ¶m_binds, update, this](auto item, auto i) { - if (is_auto_key(iguana::get_name(), iguana::get_name(i).data()) && - !update) { + iguana::for_each(t, [&t, ¶m_binds, type, this](auto item, auto i) { + if (type == OptType::insert && + is_auto_key(iguana::get_name(i).data())) { return; } set_param_bind(param_binds, t.*item); }); + if (type == OptType::update) { + iguana::for_each(t, [&t, ¶m_binds, this](auto item, auto i) { + if (is_conflict_key( + "`" + std::string(iguana::get_name(i).data()) + "`")) { + set_param_bind(param_binds, t.*item); + } + }); + } + if (mysql_stmt_bind_param(stmt_, ¶m_binds[0])) { set_last_error(mysql_stmt_error(stmt_)); return INT_MIN; @@ -648,9 +667,39 @@ class mysql { } template - int insert_impl(bool update, const T &t, bool get_insert_id = false, + int insert_impl(OptType type, const T &t, bool get_insert_id, Args &&...args) { - std::string sql = generate_insert_sql(update); + std::string sql = generate_insert_sql(type == OptType::insert); + if (insert_or_update_impl(t, sql, type) == INT_MIN) { + return INT_MIN; + } + return get_insert_id ? stmt_->mysql->insert_id : 1; + } + + template + int insert_impl(OptType type, const std::vector &v, bool get_insert_id, + Args &&...args) { + std::string sql = generate_insert_sql(type == OptType::insert); + if (insert_or_update_impl(v, sql, type) == INT_MIN) { + return INT_MIN; + } + return get_insert_id ? stmt_->mysql->insert_id : (int)v.size(); + } + + template + int update_impl(const T &t, Args &&...args) { + std::string sql = generate_update_sql(std::forward(args)...); + return insert_or_update_impl(t, sql, OptType::update); + } + + template + int update_impl(const std::vector &v, Args &&...args) { + std::string sql = generate_update_sql(std::forward(args)...); + return insert_or_update_impl(v, sql, OptType::update); + } + + template + int insert_or_update_impl(const T &t, const std::string &sql, OptType type) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif @@ -667,18 +716,17 @@ class mysql { auto guard = guard_statment(stmt_); - if (stmt_execute(update, t) == INT_MIN) { + if (stmt_execute(type, t) == INT_MIN) { set_last_error(mysql_stmt_error(stmt_)); return INT_MIN; } - return get_insert_id ? stmt_->mysql->insert_id : 1; + return 1; } - template - int insert_impl(bool update, const std::vector &t, - bool get_insert_id = false, Args &&...args) { - std::string sql = generate_insert_sql(update); + template + int insert_or_update_impl(const std::vector &v, const std::string &sql, + OptType type) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif @@ -699,15 +747,14 @@ class mysql { return INT_MIN; } - for (auto &item : t) { - if (stmt_execute(update, item) == INT_MIN) { + for (auto &item : v) { + if (stmt_execute(type, item) == INT_MIN) { rollback(); return INT_MIN; } } - return commit() ? (get_insert_id ? stmt_->mysql->insert_id : (int)t.size()) - : INT_MIN; + return commit() ? (int)v.size() : INT_MIN; } template diff --git a/include/postgresql.hpp b/include/postgresql.hpp index 59888d85..fb23b5f0 100644 --- a/include/postgresql.hpp +++ b/include/postgresql.hpp @@ -75,22 +75,32 @@ class postgresql { template constexpr int insert(const T &t, Args &&...args) { - return insert_impl(false, t, std::forward(args)...); + return insert_impl(OptType::insert, t, std::forward(args)...); } template constexpr int insert(const std::vector &v, Args &&...args) { - return insert_impl(false, v, std::forward(args)...); + return insert_impl(OptType::insert, v, std::forward(args)...); + } + + template + constexpr int replace(const T &t, Args &&...args) { + return insert_impl(OptType::replace, t, std::forward(args)...); + } + + template + constexpr int replace(const std::vector &v, Args &&...args) { + return insert_impl(OptType::replace, v, std::forward(args)...); } template constexpr int update(const T &t, Args &&...args) { - return insert_impl(true, t, std::forward(args)...); + return update_impl(t, std::forward(args)...); } template constexpr int update(const std::vector &v, Args &&...args) { - return insert_impl(true, v, std::forward(args)...); + return update_impl(v, std::forward(args)...); } template @@ -359,16 +369,24 @@ class postgresql { } template - constexpr int stmt_execute(bool update, const T &t) { + constexpr int stmt_execute(OptType type, const T &t) { std::vector> param_values; - iguana::for_each(t, [&t, ¶m_values, update, this](auto item, auto i) { - if (is_auto_key(iguana::get_name(), iguana::get_name(i).data()) && - !update) { + iguana::for_each(t, [&t, ¶m_values, type, this](auto item, auto i) { + if (type == OptType::insert && + is_auto_key(iguana::get_name(i).data())) { return; } set_param_values(param_values, t.*item); }); + if (type == OptType::update) { + iguana::for_each(t, [&t, ¶m_values, this](auto item, auto i) { + if (is_conflict_key(iguana::get_name(i).data())) { + set_param_values(param_values, t.*item); + } + }); + } + if (param_values.empty()) return INT_MIN; @@ -385,26 +403,46 @@ class postgresql { } template - constexpr int insert_impl(bool update, const T &t, Args &&...args) { - std::string sql = - update ? generate_update_sql(std::forward(args)...) - : generate_insert_sql(update); + constexpr int insert_impl(OptType type, const T &t, Args &&...args) { + std::string sql = generate_insert_sql(type == OptType::insert, + std::forward(args)...); + return insert_or_update_impl(t, sql, type); + } + + template + constexpr int insert_impl(OptType type, const std::vector &v, + Args &&...args) { + std::string sql = generate_insert_sql(type == OptType::insert, + std::forward(args)...); + return insert_or_update_impl(v, sql, type); + } + + template + int update_impl(const T &t, Args &&...args) { + std::string sql = generate_update_sql(std::forward(args)...); + return insert_or_update_impl(t, sql, OptType::update); + } + + template + int update_impl(const std::vector &v, Args &&...args) { + std::string sql = generate_update_sql(std::forward(args)...); + return insert_or_update_impl(v, sql, OptType::update); + } + + template + int insert_or_update_impl(const T &t, const std::string &sql, OptType type) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif if (!prepare(sql)) { return INT_MIN; } - - return stmt_execute(update, t); + return stmt_execute(type, t); } - template - constexpr int insert_impl(bool update, const std::vector &v, - Args &&...args) { - std::string sql = - update ? generate_update_sql(std::forward(args)...) - : generate_insert_sql(update); + template + int insert_or_update_impl(const std::vector &v, const std::string &sql, + OptType type) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif @@ -417,7 +455,7 @@ class postgresql { } for (auto &item : v) { - if (stmt_execute(update, item) == INT_MIN) { + if (stmt_execute(type, item) == INT_MIN) { rollback(); return INT_MIN; } @@ -429,45 +467,6 @@ class postgresql { return (int)v.size(); } - template - inline std::string generate_update_sql(Args &&...args) { - constexpr auto SIZE = iguana::get_value(); - std::string sql = "insert into "; - auto name = get_name(); - append(sql, name.data()); - int index = 0; - std::string set; - std::string fields = "("; - std::string values = "values("; - for (auto i = 0; i < SIZE; ++i) { - std::string field_name = iguana::get_name(i).data(); - std::string value = "$" + std::to_string(++index); - set += field_name + "=" + value; - fields += field_name; - values += value; - if (i < SIZE - 1) { - fields += ","; - values += ","; - set += ","; - } - else { - fields += ")"; - values += ")"; - set += ";"; - } - } - std::string conflict = "on conflict("; - if constexpr (sizeof...(Args) > 0) { - append(conflict, args...); - } - else { - conflict += get_conflict_key(iguana::get_name()); - } - conflict += ")"; - append(sql, fields, values, conflict, "do update set", set); - return sql; - } - template constexpr void set_param_values(std::vector> ¶m_values, T &&value) { diff --git a/include/sqlite.hpp b/include/sqlite.hpp index dd85035e..1ca43627 100644 --- a/include/sqlite.hpp +++ b/include/sqlite.hpp @@ -73,23 +73,35 @@ class sqlite { template int insert(const T &t, bool get_insert_id = false, Args &&...args) { - return insert_impl(false, t, get_insert_id, std::forward(args)...); + return insert_impl(OptType::insert, t, get_insert_id, + std::forward(args)...); } template int insert(const std::vector &t, bool get_insert_id = false, Args &&...args) { - return insert_impl(false, t, get_insert_id, std::forward(args)...); + return insert_impl(OptType::insert, t, get_insert_id, + std::forward(args)...); + } + + template + int replace(const T &t, Args &&...args) { + return insert_impl(OptType::replace, t, false, std::forward(args)...); + } + + template + int replace(const std::vector &t, Args &&...args) { + return insert_impl(OptType::replace, t, false, std::forward(args)...); } template int update(const T &t, Args &&...args) { - return insert_impl(true, t, false, std::forward(args)...); + return update_impl(t, std::forward(args)...); } template int update(const std::vector &t, Args &&...args) { - return insert_impl(true, t, false, std::forward(args)...); + return update_impl(t, std::forward(args)...); } template @@ -357,20 +369,31 @@ class sqlite { } template - constexpr int stmt_execute(bool update, const T &t) { + constexpr int stmt_execute(OptType type, const T &t) { int index = 0; bool bind_ok = true; - iguana::for_each(t, [&t, &bind_ok, &index, update, this](auto item, - auto i) { - if ((is_auto_key(iguana::get_name(), iguana::get_name(i).data()) || - !bind_ok) && - !update) { + iguana::for_each(t, [&t, &bind_ok, &index, type, this](auto item, auto i) { + if ((type == OptType::insert && + is_auto_key(iguana::get_name(i).data())) || + !bind_ok) { return; } bind_ok = set_param_bind(t.*item, index + 1); index++; }); + if (type == OptType::update) { + iguana::for_each(t, [&t, &bind_ok, &index, this](auto item, auto i) { + if (!bind_ok) { + return; + } + if (is_conflict_key(iguana::get_name(i).data())) { + bind_ok = set_param_bind(t.*item, index + 1); + index++; + } + }); + } + if (!bind_ok) { set_last_error(sqlite3_errmsg(handle_)); return INT_MIN; @@ -463,9 +486,39 @@ class sqlite { } template - int insert_impl(bool update, const T &t, bool get_insert_id = false, + int insert_impl(OptType type, const T &t, bool get_insert_id, Args &&...args) { - std::string sql = generate_insert_sql(update); + std::string sql = generate_insert_sql(type == OptType::insert); + if (insert_or_update_impl(t, sql, type) == INT_MIN) { + return INT_MIN; + } + return get_insert_id ? sqlite3_last_insert_rowid(handle_) : 1; + } + + template + int insert_impl(OptType type, const std::vector &v, bool get_insert_id, + Args &&...args) { + std::string sql = generate_insert_sql(type == OptType::insert); + if (insert_or_update_impl(v, sql, type) == INT_MIN) { + return INT_MIN; + } + return get_insert_id ? sqlite3_last_insert_rowid(handle_) : (int)v.size(); + } + + template + int update_impl(const T &t, Args &&...args) { + std::string sql = generate_update_sql(std::forward(args)...); + return insert_or_update_impl(t, sql, OptType::update); + } + + template + int update_impl(const std::vector &v, Args &&...args) { + std::string sql = generate_update_sql(std::forward(args)...); + return insert_or_update_impl(v, sql, OptType::update); + } + + template + int insert_or_update_impl(const T &t, const std::string &sql, OptType type) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif @@ -477,18 +530,17 @@ class sqlite { auto guard = guard_statment(stmt_); - if (stmt_execute(update, t) == INT_MIN) { + if (stmt_execute(type, t) == INT_MIN) { set_last_error(sqlite3_errmsg(handle_)); return INT_MIN; } - return get_insert_id ? sqlite3_last_insert_rowid(handle_) : 1; + return 1; } - template - int insert_impl(bool update, const std::vector &v, - bool get_insert_id = false, Args &&...args) { - std::string sql = generate_insert_sql(update); + template + int insert_or_update_impl(const std::vector &v, const std::string &sql, + OptType type) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif @@ -505,7 +557,7 @@ class sqlite { } for (auto &item : v) { - if (stmt_execute(update, item) == INT_MIN) { + if (stmt_execute(type, item) == INT_MIN) { rollback(); return INT_MIN; } @@ -517,9 +569,7 @@ class sqlite { } } - return commit() ? (get_insert_id ? sqlite3_last_insert_rowid(handle_) - : (int)v.size()) - : INT_MIN; + return commit() ? (int)v.size() : INT_MIN; } private: diff --git a/include/utility.hpp b/include/utility.hpp index 91201965..42b8951a 100644 --- a/include/utility.hpp +++ b/include/utility.hpp @@ -19,9 +19,10 @@ inline int add_auto_key_field(std::string_view key, std::string_view value) { return 0; } -inline auto is_auto_key(std::string_view key, std::string_view value) { - auto it = g_ormpp_auto_key_map.find(key); - return it == g_ormpp_auto_key_map.end() ? false : it->second == value; +template +inline auto is_auto_key(std::string_view field_name) { + auto it = g_ormpp_auto_key_map.find(iguana::get_name()); + return it == g_ormpp_auto_key_map.end() ? false : it->second == field_name; } #define REGISTER_AUTO_KEY(STRUCT_NAME, KEY) \ @@ -115,6 +116,7 @@ inline auto sort_tuple(const std::tuple &tp) { } } +enum class OptType { insert, update, replace }; enum class DBType { mysql, sqlite, postgresql, unknown }; template @@ -189,7 +191,7 @@ inline std::string get_fields() { } for (const auto &it : iguana::Reflect_members::arr()) { #ifdef ORMPP_ENABLE_MYSQL - fields += "`" + std::string(it.data()) + "`"; + append(fields, "`", std::string(it.data()), "`"); #else fields += it.data(); #endif @@ -199,9 +201,83 @@ inline std::string get_fields() { return fields; } +template >> +inline std::vector get_conflict_keys() { + static std::vector res; + if (!res.empty()) { + return res; + } + std::stringstream s(get_conflict_key(iguana::get_name()).data()); + while (s.good()) { + std::string str; + getline(s, str, ','); + if (str.front() == ' ') { + str.erase(0); + } + if (str.back() == ' ') { + str.pop_back(); + } +#ifdef ORMPP_ENABLE_MYSQL + str.insert(0, "`"); + str.append("`"); +#endif + res.emplace_back(str); + } + return res; +} + template -inline std::string generate_insert_sql(bool replace) { - std::string sql = replace ? "replace into " : "insert into "; +inline auto is_conflict_key(std::string_view field_name) { + for (const auto &it : get_conflict_keys()) { + if (it == field_name) { + return true; + } + } + return false; +} + +template +inline std::string generate_insert_sql(bool insert, Args &&...args) { +#ifdef ORMPP_ENABLE_PG + if (!insert) { + constexpr auto SIZE = iguana::get_value(); + std::string sql = "insert into "; + auto name = get_name(); + append(sql, name.data()); + int index = 0; + std::string set; + std::string fields = "("; + std::string values = "values("; + for (auto i = 0; i < SIZE; ++i) { + std::string field_name = iguana::get_name(i).data(); + std::string value = "$" + std::to_string(++index); + append(set, field_name, " = ", value); + fields += field_name; + values += value; + if (i < SIZE - 1) { + fields += ","; + values += ","; + set += ","; + } + else { + fields += ")"; + values += ")"; + set += ";"; + } + } + std::string conflict = "on conflict("; + if constexpr (sizeof...(Args) > 0) { + append(conflict, args...); + } + else { + conflict += get_conflict_key(iguana::get_name()); + } + conflict += ")"; + append(sql, fields, values, conflict, "do update set", set); + return sql; + } +#endif + std::string sql = insert ? "insert into " : "replace into "; constexpr auto SIZE = iguana::get_value(); auto name = get_name(); append(sql, name.data()); @@ -211,7 +287,7 @@ inline std::string generate_insert_sql(bool replace) { std::string values = "values("; for (size_t i = 0; i < SIZE; ++i) { std::string field_name = iguana::get_name(i).data(); - if (is_auto_key(iguana::get_name(), field_name)) { + if (is_auto_key(field_name)) { continue; } #ifdef ORMPP_ENABLE_PG @@ -220,7 +296,7 @@ inline std::string generate_insert_sql(bool replace) { values += "?"; #endif #ifdef ORMPP_ENABLE_MYSQL - fields += "`" + field_name + "`"; + append(fields, "`", field_name, "`"); #else fields += field_name; #endif @@ -245,6 +321,44 @@ inline std::string generate_insert_sql(bool replace) { return sql; } +template +inline std::string generate_update_sql(Args &&...args) { + constexpr auto SIZE = iguana::get_value(); + std::string sql = "update "; + auto name = get_name(); + append(sql, name.data()); + append(sql, "set"); + + int index = 0; + std::string fields; + for (size_t i = 0; i < SIZE; ++i) { +#ifdef ORMPP_ENABLE_MYSQL + append(fields, "`", iguana::get_name(i).data(), "`"); +#else + fields += iguana::get_name(i).data(); +#endif +#ifdef ORMPP_ENABLE_PG + append(fields, " = $", std::to_string(++index)); +#else + fields += " = ?"; +#endif + if (i < SIZE - 1) { + fields += ", "; + } + } + std::string conflict = "where 1=1"; + if constexpr (sizeof...(Args) > 0) { + append(conflict, " and ", args...); + } + else { + for (const auto &it : get_conflict_keys()) { + append(conflict, " and ", it, " = ?"); + } + } + append(sql, fields, conflict); + return sql; +} + inline bool is_empty(const std::string &t) { return t.empty(); } template From 49d752c117f9fd5a331990d33b028a432a96cdec Mon Sep 17 00:00:00 2001 From: Jacyking <791026912@qq.com> Date: Wed, 13 Dec 2023 21:15:53 +0800 Subject: [PATCH 2/9] add update&replace api --- include/utility.hpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/include/utility.hpp b/include/utility.hpp index 42b8951a..51b8495e 100644 --- a/include/utility.hpp +++ b/include/utility.hpp @@ -191,7 +191,7 @@ inline std::string get_fields() { } for (const auto &it : iguana::Reflect_members::arr()) { #ifdef ORMPP_ENABLE_MYSQL - append(fields, "`", std::string(it.data()), "`"); + fields += "`" + std::string(it.data()) + "`"; #else fields += it.data(); #endif @@ -251,7 +251,7 @@ inline std::string generate_insert_sql(bool insert, Args &&...args) { for (auto i = 0; i < SIZE; ++i) { std::string field_name = iguana::get_name(i).data(); std::string value = "$" + std::to_string(++index); - append(set, field_name, " = ", value); + append(set, field_name, "=", value); fields += field_name; values += value; if (i < SIZE - 1) { @@ -296,7 +296,7 @@ inline std::string generate_insert_sql(bool insert, Args &&...args) { values += "?"; #endif #ifdef ORMPP_ENABLE_MYSQL - append(fields, "`", field_name, "`"); + fields += "`" + field_name + "`"; #else fields += field_name; #endif @@ -332,13 +332,14 @@ inline std::string generate_update_sql(Args &&...args) { int index = 0; std::string fields; for (size_t i = 0; i < SIZE; ++i) { + std::string field_name = iguana::get_name(i).data(); #ifdef ORMPP_ENABLE_MYSQL - append(fields, "`", iguana::get_name(i).data(), "`"); + fields += "`" + field_name + "`"; #else - fields += iguana::get_name(i).data(); + fields += field_name; #endif #ifdef ORMPP_ENABLE_PG - append(fields, " = $", std::to_string(++index)); + append(fields, "=", "$" + std::to_string(++index)); #else fields += " = ?"; #endif From 67b726f02f049b883f1691d872b41446567623d0 Mon Sep 17 00:00:00 2001 From: Jacyking <791026912@qq.com> Date: Wed, 13 Dec 2023 21:35:12 +0800 Subject: [PATCH 3/9] add update&replace api --- include/mysql.hpp | 20 ++++++++------------ include/sqlite.hpp | 21 +++++++++------------ include/utility.hpp | 10 +++++++--- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/include/mysql.hpp b/include/mysql.hpp index 7f800bad..403ba31f 100644 --- a/include/mysql.hpp +++ b/include/mysql.hpp @@ -670,20 +670,14 @@ class mysql { int insert_impl(OptType type, const T &t, bool get_insert_id, Args &&...args) { std::string sql = generate_insert_sql(type == OptType::insert); - if (insert_or_update_impl(t, sql, type) == INT_MIN) { - return INT_MIN; - } - return get_insert_id ? stmt_->mysql->insert_id : 1; + return insert_or_update_impl(t, sql, type, get_insert_id); } template int insert_impl(OptType type, const std::vector &v, bool get_insert_id, Args &&...args) { std::string sql = generate_insert_sql(type == OptType::insert); - if (insert_or_update_impl(v, sql, type) == INT_MIN) { - return INT_MIN; - } - return get_insert_id ? stmt_->mysql->insert_id : (int)v.size(); + return insert_or_update_impl(v, sql, type, get_insert_id); } template @@ -699,7 +693,8 @@ class mysql { } template - int insert_or_update_impl(const T &t, const std::string &sql, OptType type) { + int insert_or_update_impl(const T &t, const std::string &sql, OptType type, + bool get_insert_id = false) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif @@ -721,12 +716,12 @@ class mysql { return INT_MIN; } - return 1; + return get_insert_id ? stmt_->mysql->insert_id : 1; } template int insert_or_update_impl(const std::vector &v, const std::string &sql, - OptType type) { + OptType type, bool get_insert_id = false) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif @@ -754,7 +749,8 @@ class mysql { } } - return commit() ? (int)v.size() : INT_MIN; + return commit() ? get_insert_id ? stmt_->mysql->insert_id : (int)v.size() + : INT_MIN; } template diff --git a/include/sqlite.hpp b/include/sqlite.hpp index 1ca43627..ce35781f 100644 --- a/include/sqlite.hpp +++ b/include/sqlite.hpp @@ -489,20 +489,14 @@ class sqlite { int insert_impl(OptType type, const T &t, bool get_insert_id, Args &&...args) { std::string sql = generate_insert_sql(type == OptType::insert); - if (insert_or_update_impl(t, sql, type) == INT_MIN) { - return INT_MIN; - } - return get_insert_id ? sqlite3_last_insert_rowid(handle_) : 1; + return insert_or_update_impl(t, sql, type, get_insert_id); } template int insert_impl(OptType type, const std::vector &v, bool get_insert_id, Args &&...args) { std::string sql = generate_insert_sql(type == OptType::insert); - if (insert_or_update_impl(v, sql, type) == INT_MIN) { - return INT_MIN; - } - return get_insert_id ? sqlite3_last_insert_rowid(handle_) : (int)v.size(); + return insert_or_update_impl(v, sql, type, get_insert_id); } template @@ -518,7 +512,8 @@ class sqlite { } template - int insert_or_update_impl(const T &t, const std::string &sql, OptType type) { + int insert_or_update_impl(const T &t, const std::string &sql, OptType type, + bool get_insert_id = false) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif @@ -535,12 +530,12 @@ class sqlite { return INT_MIN; } - return 1; + return get_insert_id ? sqlite3_last_insert_rowid(handle_) : 1; } template int insert_or_update_impl(const std::vector &v, const std::string &sql, - OptType type) { + OptType type, bool get_insert_id = false) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif @@ -569,7 +564,9 @@ class sqlite { } } - return commit() ? (int)v.size() : INT_MIN; + return commit() ? get_insert_id ? sqlite3_last_insert_rowid(handle_) + : (int)v.size() + : INT_MIN; } private: diff --git a/include/utility.hpp b/include/utility.hpp index 51b8495e..28a4c87b 100644 --- a/include/utility.hpp +++ b/include/utility.hpp @@ -339,7 +339,7 @@ inline std::string generate_update_sql(Args &&...args) { fields += field_name; #endif #ifdef ORMPP_ENABLE_PG - append(fields, "=", "$" + std::to_string(++index)); + append(fields, " =", "$" + std::to_string(++index)); #else fields += " = ?"; #endif @@ -349,11 +349,15 @@ inline std::string generate_update_sql(Args &&...args) { } std::string conflict = "where 1=1"; if constexpr (sizeof...(Args) > 0) { - append(conflict, " and ", args...); + append(conflict, " and", args...); } else { for (const auto &it : get_conflict_keys()) { - append(conflict, " and ", it, " = ?"); +#ifdef ORMPP_ENABLE_PG + append(conflict, " and", it, "=", "$" + std::to_string(++index)); +#else + append(conflict, " and", it, "= ?"); +#endif } } append(sql, fields, conflict); From a48743b9c5770d81b09717322df734f89ee4b536 Mon Sep 17 00:00:00 2001 From: Jacyking <791026912@qq.com> Date: Wed, 13 Dec 2023 21:49:52 +0800 Subject: [PATCH 4/9] add update&replace api --- include/mysql.hpp | 25 +++++++++++++++---------- include/postgresql.hpp | 25 +++++++++++++++---------- include/sqlite.hpp | 25 +++++++++++++++---------- include/utility.hpp | 3 ++- 4 files changed, 47 insertions(+), 31 deletions(-) diff --git a/include/mysql.hpp b/include/mysql.hpp index 403ba31f..5f553a7c 100644 --- a/include/mysql.hpp +++ b/include/mysql.hpp @@ -629,7 +629,7 @@ class mysql { } template - int stmt_execute(OptType type, const T &t) { + int stmt_execute(const T &t, OptType type, bool condition) { std::vector param_binds; iguana::for_each(t, [&t, ¶m_binds, type, this](auto item, auto i) { if (type == OptType::insert && @@ -639,7 +639,7 @@ class mysql { set_param_bind(param_binds, t.*item); }); - if (type == OptType::update) { + if (condition && type == OptType::update) { iguana::for_each(t, [&t, ¶m_binds, this](auto item, auto i) { if (is_conflict_key( "`" + std::string(iguana::get_name(i).data()) + "`")) { @@ -682,19 +682,23 @@ class mysql { template int update_impl(const T &t, Args &&...args) { - std::string sql = generate_update_sql(std::forward(args)...); - return insert_or_update_impl(t, sql, OptType::update); + bool condition = true; + std::string sql = + generate_update_sql(condition, std::forward(args)...); + return insert_or_update_impl(t, sql, OptType::update, false, condition); } template int update_impl(const std::vector &v, Args &&...args) { - std::string sql = generate_update_sql(std::forward(args)...); - return insert_or_update_impl(v, sql, OptType::update); + bool condition = true; + std::string sql = + generate_update_sql(condition, std::forward(args)...); + return insert_or_update_impl(v, sql, OptType::update, false, condition); } template int insert_or_update_impl(const T &t, const std::string &sql, OptType type, - bool get_insert_id = false) { + bool get_insert_id = false, bool condition = true) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif @@ -711,7 +715,7 @@ class mysql { auto guard = guard_statment(stmt_); - if (stmt_execute(type, t) == INT_MIN) { + if (stmt_execute(t, type, condition) == INT_MIN) { set_last_error(mysql_stmt_error(stmt_)); return INT_MIN; } @@ -721,7 +725,8 @@ class mysql { template int insert_or_update_impl(const std::vector &v, const std::string &sql, - OptType type, bool get_insert_id = false) { + OptType type, bool get_insert_id = false, + bool condition = true) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif @@ -743,7 +748,7 @@ class mysql { } for (auto &item : v) { - if (stmt_execute(type, item) == INT_MIN) { + if (stmt_execute(item, type, condition) == INT_MIN) { rollback(); return INT_MIN; } diff --git a/include/postgresql.hpp b/include/postgresql.hpp index fb23b5f0..98c53603 100644 --- a/include/postgresql.hpp +++ b/include/postgresql.hpp @@ -369,7 +369,7 @@ class postgresql { } template - constexpr int stmt_execute(OptType type, const T &t) { + constexpr int stmt_execute(const T &t, OptType type, bool condition) { std::vector> param_values; iguana::for_each(t, [&t, ¶m_values, type, this](auto item, auto i) { if (type == OptType::insert && @@ -379,7 +379,7 @@ class postgresql { set_param_values(param_values, t.*item); }); - if (type == OptType::update) { + if (condition && type == OptType::update) { iguana::for_each(t, [&t, ¶m_values, this](auto item, auto i) { if (is_conflict_key(iguana::get_name(i).data())) { set_param_values(param_values, t.*item); @@ -419,30 +419,35 @@ class postgresql { template int update_impl(const T &t, Args &&...args) { - std::string sql = generate_update_sql(std::forward(args)...); - return insert_or_update_impl(t, sql, OptType::update); + bool condition = true; + std::string sql = + generate_update_sql(condition, std::forward(args)...); + return insert_or_update_impl(t, sql, OptType::update, condition); } template int update_impl(const std::vector &v, Args &&...args) { - std::string sql = generate_update_sql(std::forward(args)...); - return insert_or_update_impl(v, sql, OptType::update); + bool condition = true; + std::string sql = + generate_update_sql(condition, std::forward(args)...); + return insert_or_update_impl(v, sql, OptType::update, condition); } template - int insert_or_update_impl(const T &t, const std::string &sql, OptType type) { + int insert_or_update_impl(const T &t, const std::string &sql, OptType type, + bool condition = true) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif if (!prepare(sql)) { return INT_MIN; } - return stmt_execute(type, t); + return stmt_execute(t, type, condition); } template int insert_or_update_impl(const std::vector &v, const std::string &sql, - OptType type) { + OptType type, bool condition = true) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif @@ -455,7 +460,7 @@ class postgresql { } for (auto &item : v) { - if (stmt_execute(type, item) == INT_MIN) { + if (stmt_execute(item, type, condition) == INT_MIN) { rollback(); return INT_MIN; } diff --git a/include/sqlite.hpp b/include/sqlite.hpp index ce35781f..0771f0e8 100644 --- a/include/sqlite.hpp +++ b/include/sqlite.hpp @@ -369,7 +369,7 @@ class sqlite { } template - constexpr int stmt_execute(OptType type, const T &t) { + constexpr int stmt_execute(const T &t, OptType type, bool condition) { int index = 0; bool bind_ok = true; iguana::for_each(t, [&t, &bind_ok, &index, type, this](auto item, auto i) { @@ -382,7 +382,7 @@ class sqlite { index++; }); - if (type == OptType::update) { + if (condition && type == OptType::update) { iguana::for_each(t, [&t, &bind_ok, &index, this](auto item, auto i) { if (!bind_ok) { return; @@ -501,19 +501,23 @@ class sqlite { template int update_impl(const T &t, Args &&...args) { - std::string sql = generate_update_sql(std::forward(args)...); - return insert_or_update_impl(t, sql, OptType::update); + bool condition = true; + std::string sql = + generate_update_sql(condition, std::forward(args)...); + return insert_or_update_impl(t, sql, OptType::update, false, condition); } template int update_impl(const std::vector &v, Args &&...args) { - std::string sql = generate_update_sql(std::forward(args)...); - return insert_or_update_impl(v, sql, OptType::update); + bool condition = true; + std::string sql = + generate_update_sql(condition, std::forward(args)...); + return insert_or_update_impl(v, sql, OptType::update, false, condition); } template int insert_or_update_impl(const T &t, const std::string &sql, OptType type, - bool get_insert_id = false) { + bool get_insert_id = false, bool condition = true) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif @@ -525,7 +529,7 @@ class sqlite { auto guard = guard_statment(stmt_); - if (stmt_execute(type, t) == INT_MIN) { + if (stmt_execute(t, type, condition) == INT_MIN) { set_last_error(sqlite3_errmsg(handle_)); return INT_MIN; } @@ -535,7 +539,8 @@ class sqlite { template int insert_or_update_impl(const std::vector &v, const std::string &sql, - OptType type, bool get_insert_id = false) { + OptType type, bool get_insert_id = false, + bool condition = true) { #ifdef ORMPP_ENABLE_LOG std::cout << sql << std::endl; #endif @@ -552,7 +557,7 @@ class sqlite { } for (auto &item : v) { - if (stmt_execute(type, item) == INT_MIN) { + if (stmt_execute(item, type, condition) == INT_MIN) { rollback(); return INT_MIN; } diff --git a/include/utility.hpp b/include/utility.hpp index 28a4c87b..7c35ec2e 100644 --- a/include/utility.hpp +++ b/include/utility.hpp @@ -322,7 +322,7 @@ inline std::string generate_insert_sql(bool insert, Args &&...args) { } template -inline std::string generate_update_sql(Args &&...args) { +inline std::string generate_update_sql(bool &condition, Args &&...args) { constexpr auto SIZE = iguana::get_value(); std::string sql = "update "; auto name = get_name(); @@ -350,6 +350,7 @@ inline std::string generate_update_sql(Args &&...args) { std::string conflict = "where 1=1"; if constexpr (sizeof...(Args) > 0) { append(conflict, " and", args...); + condition = false; } else { for (const auto &it : get_conflict_keys()) { From 05638cea43adc6caee5ce023688ce2656a699548 Mon Sep 17 00:00:00 2001 From: Jacyking <791026912@qq.com> Date: Thu, 14 Dec 2023 10:28:40 +0800 Subject: [PATCH 5/9] add update replace ut --- include/mysql.hpp | 6 ++- tests/test_ormpp.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/include/mysql.hpp b/include/mysql.hpp index 5f553a7c..a8275e73 100644 --- a/include/mysql.hpp +++ b/include/mysql.hpp @@ -641,8 +641,10 @@ class mysql { if (condition && type == OptType::update) { iguana::for_each(t, [&t, ¶m_binds, this](auto item, auto i) { - if (is_conflict_key( - "`" + std::string(iguana::get_name(i).data()) + "`")) { + std::string field_name = "`"; + field_name += iguana::get_name(i).data(); + field_name += "`"; + if (is_conflict_key(field_name)) { set_param_bind(param_binds, t.*item); } }); diff --git a/tests/test_ormpp.cpp b/tests/test_ormpp.cpp index 7f192b69..d7f89814 100644 --- a/tests/test_ormpp.cpp +++ b/tests/test_ormpp.cpp @@ -494,6 +494,101 @@ TEST_CASE("insert query") { } } +TEST_CASE("update replace") { +#ifdef ORMPP_ENABLE_MYSQL + dbng mysql; + if (mysql.connect(ip, username, password, db)) { + mysql.execute("drop table if exists person"); + mysql.create_datatable(ormpp_auto_key{"id"}); + mysql.insert({"purecpp", 100}); + auto vec = mysql.query(); + CHECK(vec.size() == 1); + vec.front().name = "update"; + vec.front().age = 200; + mysql.update(vec.front()); + vec = mysql.query(); + CHECK(vec.size() == 1); + CHECK(vec.front().name == "update"); + CHECK(vec.front().age == 200); + mysql.update({"purecpp", 100}, "id=1"); + vec = mysql.query(); + CHECK(vec.size() == 1); + CHECK(vec.front().name == "purecpp"); + CHECK(vec.front().age == 100); + vec.front().name = "update"; + vec.front().age = 200; + mysql.replace(vec.front()); + vec = mysql.query(); + CHECK(vec.size() == 1); + CHECK(vec.front().name == "update"); + CHECK(vec.front().age == 200); + } +#endif +#ifdef ORMPP_ENABLE_PG + dbng postgres; + if (postgres.connect(ip, username, password, db)) { + postgres.execute("drop table if exists person"); + postgres.create_datatable(ormpp_auto_key{"id"}); + postgres.insert({"purecpp", 100}); + auto vec = postgres.query(); + CHECK(vec.size() == 1); + vec.front().name = "update"; + vec.front().age = 200; + postgres.update(vec.front()); + vec = postgres.query(); + CHECK(vec.size() == 1); + CHECK(vec.front().name == "update"); + CHECK(vec.front().age == 200); + postgres.update({"purecpp", 100}, "id=1"); + vec = postgres.query(); + CHECK(vec.size() == 1); + CHECK(vec.front().name == "purecpp"); + CHECK(vec.front().age == 100); + vec.front().name = "update"; + vec.front().age = 200; + postgres.replace(vec.front()); + vec = postgres.query(); + CHECK(vec.size() == 1); + CHECK(vec.front().name == "update"); + CHECK(vec.front().age == 200); + postgres.replace({"purecpp", 100, 1}, "id"); + vec = postgres.query(); + CHECK(vec.size() == 1); + CHECK(vec.front().name == "purecpp"); + CHECK(vec.front().age == 100); + } +#endif +#ifdef ORMPP_ENABLE_SQLITE3 + dbng sqlite; + if (sqlite.connect(db)) { + sqlite.execute("drop table if exists person"); + sqlite.create_datatable(ormpp_auto_key{"id"}); + sqlite.insert({"purecpp", 100}); + auto vec = sqlite.query(); + CHECK(vec.size() == 1); + vec.front().name = "update"; + vec.front().age = 200; + sqlite.update(vec.front()); + vec = sqlite.query(); + CHECK(vec.size() == 1); + CHECK(vec.front().name == "update"); + CHECK(vec.front().age == 200); + sqlite.update({"purecpp", 100}, "id=1"); + vec = sqlite.query(); + CHECK(vec.size() == 1); + CHECK(vec.front().name == "purecpp"); + CHECK(vec.front().age == 100); + vec.front().name = "update"; + vec.front().age = 200; + sqlite.replace(vec.front()); + vec = sqlite.query(); + CHECK(vec.size() == 1); + CHECK(vec.front().name == "update"); + CHECK(vec.front().age == 200); + } +#endif +} + TEST_CASE("update") { ormpp_key key{"code"}; ormpp_not_null not_null{{"code", "age"}}; From 81f77c99f30a7a079f7c043e18ea5c16fb6dd6ce Mon Sep 17 00:00:00 2001 From: Jacyking <791026912@qq.com> Date: Thu, 14 Dec 2023 10:42:10 +0800 Subject: [PATCH 6/9] add update&replace ut --- include/utility.hpp | 2 +- tests/test_ormpp.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/utility.hpp b/include/utility.hpp index 7c35ec2e..3850dde9 100644 --- a/include/utility.hpp +++ b/include/utility.hpp @@ -287,7 +287,7 @@ inline std::string generate_insert_sql(bool insert, Args &&...args) { std::string values = "values("; for (size_t i = 0; i < SIZE; ++i) { std::string field_name = iguana::get_name(i).data(); - if (is_auto_key(field_name)) { + if (insert && is_auto_key(field_name)) { continue; } #ifdef ORMPP_ENABLE_PG diff --git a/tests/test_ormpp.cpp b/tests/test_ormpp.cpp index d7f89814..bfc57d13 100644 --- a/tests/test_ormpp.cpp +++ b/tests/test_ormpp.cpp @@ -510,7 +510,7 @@ TEST_CASE("update replace") { CHECK(vec.size() == 1); CHECK(vec.front().name == "update"); CHECK(vec.front().age == 200); - mysql.update({"purecpp", 100}, "id=1"); + mysql.update({"purecpp", 100}, "id=1"); vec = mysql.query(); CHECK(vec.size() == 1); CHECK(vec.front().name == "purecpp"); @@ -539,7 +539,7 @@ TEST_CASE("update replace") { CHECK(vec.size() == 1); CHECK(vec.front().name == "update"); CHECK(vec.front().age == 200); - postgres.update({"purecpp", 100}, "id=1"); + postgres.update({"purecpp", 100}, "id=1"); vec = postgres.query(); CHECK(vec.size() == 1); CHECK(vec.front().name == "purecpp"); @@ -551,7 +551,7 @@ TEST_CASE("update replace") { CHECK(vec.size() == 1); CHECK(vec.front().name == "update"); CHECK(vec.front().age == 200); - postgres.replace({"purecpp", 100, 1}, "id"); + postgres.replace({"purecpp", 100, 1}, "id"); vec = postgres.query(); CHECK(vec.size() == 1); CHECK(vec.front().name == "purecpp"); @@ -573,7 +573,7 @@ TEST_CASE("update replace") { CHECK(vec.size() == 1); CHECK(vec.front().name == "update"); CHECK(vec.front().age == 200); - sqlite.update({"purecpp", 100}, "id=1"); + sqlite.update({"purecpp", 100}, "id=1"); vec = sqlite.query(); CHECK(vec.size() == 1); CHECK(vec.front().name == "purecpp"); From 1466d33e32af54b2c5e74848fe07e236780ee75f Mon Sep 17 00:00:00 2001 From: Jacyking <791026912@qq.com> Date: Thu, 14 Dec 2023 10:55:46 +0800 Subject: [PATCH 7/9] add update replace ut --- tests/test_ormpp.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_ormpp.cpp b/tests/test_ormpp.cpp index bfc57d13..b62f69eb 100644 --- a/tests/test_ormpp.cpp +++ b/tests/test_ormpp.cpp @@ -23,7 +23,7 @@ using namespace ormpp; #ifdef ORMPP_ENABLE_PG const char *password = "123456"; #else -const char *password = ""; +const char *password = "123456"; #endif const char *ip = "127.0.0.1"; const char *username = "root"; @@ -500,7 +500,7 @@ TEST_CASE("update replace") { if (mysql.connect(ip, username, password, db)) { mysql.execute("drop table if exists person"); mysql.create_datatable(ormpp_auto_key{"id"}); - mysql.insert({"purecpp", 100}); + mysql.insert({"purecpp", 100, 1}); auto vec = mysql.query(); CHECK(vec.size() == 1); vec.front().name = "update"; @@ -529,7 +529,7 @@ TEST_CASE("update replace") { if (postgres.connect(ip, username, password, db)) { postgres.execute("drop table if exists person"); postgres.create_datatable(ormpp_auto_key{"id"}); - postgres.insert({"purecpp", 100}); + postgres.insert({"purecpp", 100, 1}); auto vec = postgres.query(); CHECK(vec.size() == 1); vec.front().name = "update"; @@ -563,7 +563,7 @@ TEST_CASE("update replace") { if (sqlite.connect(db)) { sqlite.execute("drop table if exists person"); sqlite.create_datatable(ormpp_auto_key{"id"}); - sqlite.insert({"purecpp", 100}); + sqlite.insert({"purecpp", 100, 1}); auto vec = sqlite.query(); CHECK(vec.size() == 1); vec.front().name = "update"; From b281b05c7a41756bd6f884d477a6219bf884f2e3 Mon Sep 17 00:00:00 2001 From: Jacyking <791026912@qq.com> Date: Thu, 14 Dec 2023 10:59:17 +0800 Subject: [PATCH 8/9] add update&replace ut --- tests/test_ormpp.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_ormpp.cpp b/tests/test_ormpp.cpp index b62f69eb..33a4898c 100644 --- a/tests/test_ormpp.cpp +++ b/tests/test_ormpp.cpp @@ -500,7 +500,7 @@ TEST_CASE("update replace") { if (mysql.connect(ip, username, password, db)) { mysql.execute("drop table if exists person"); mysql.create_datatable(ormpp_auto_key{"id"}); - mysql.insert({"purecpp", 100, 1}); + mysql.insert({"purecpp", 100}); auto vec = mysql.query(); CHECK(vec.size() == 1); vec.front().name = "update"; @@ -510,7 +510,7 @@ TEST_CASE("update replace") { CHECK(vec.size() == 1); CHECK(vec.front().name == "update"); CHECK(vec.front().age == 200); - mysql.update({"purecpp", 100}, "id=1"); + mysql.update({"purecpp", 100, 1}, "id=1"); vec = mysql.query(); CHECK(vec.size() == 1); CHECK(vec.front().name == "purecpp"); @@ -529,7 +529,7 @@ TEST_CASE("update replace") { if (postgres.connect(ip, username, password, db)) { postgres.execute("drop table if exists person"); postgres.create_datatable(ormpp_auto_key{"id"}); - postgres.insert({"purecpp", 100, 1}); + postgres.insert({"purecpp", 100}); auto vec = postgres.query(); CHECK(vec.size() == 1); vec.front().name = "update"; @@ -539,7 +539,7 @@ TEST_CASE("update replace") { CHECK(vec.size() == 1); CHECK(vec.front().name == "update"); CHECK(vec.front().age == 200); - postgres.update({"purecpp", 100}, "id=1"); + postgres.update({"purecpp", 100, 1}, "id=1"); vec = postgres.query(); CHECK(vec.size() == 1); CHECK(vec.front().name == "purecpp"); @@ -563,7 +563,7 @@ TEST_CASE("update replace") { if (sqlite.connect(db)) { sqlite.execute("drop table if exists person"); sqlite.create_datatable(ormpp_auto_key{"id"}); - sqlite.insert({"purecpp", 100, 1}); + sqlite.insert({"purecpp", 100}); auto vec = sqlite.query(); CHECK(vec.size() == 1); vec.front().name = "update"; @@ -573,7 +573,7 @@ TEST_CASE("update replace") { CHECK(vec.size() == 1); CHECK(vec.front().name == "update"); CHECK(vec.front().age == 200); - sqlite.update({"purecpp", 100}, "id=1"); + sqlite.update({"purecpp", 100, 1}, "id=1"); vec = sqlite.query(); CHECK(vec.size() == 1); CHECK(vec.front().name == "purecpp"); From e14055629502f2c01085bc7a413c5e019e3827aa Mon Sep 17 00:00:00 2001 From: Jacyking <791026912@qq.com> Date: Thu, 14 Dec 2023 11:01:22 +0800 Subject: [PATCH 9/9] add update&replace ut --- tests/test_ormpp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_ormpp.cpp b/tests/test_ormpp.cpp index 33a4898c..7071597d 100644 --- a/tests/test_ormpp.cpp +++ b/tests/test_ormpp.cpp @@ -23,7 +23,7 @@ using namespace ormpp; #ifdef ORMPP_ENABLE_PG const char *password = "123456"; #else -const char *password = "123456"; +const char *password = ""; #endif const char *ip = "127.0.0.1"; const char *username = "root";