EXPECT_TRUE(static_cast<bool>(r));
}
+TEST_F(DatabaseTest, test_reuse_result) {
+ tizen_base::Database db(TEST_DB, SQLITE_OPEN_READWRITE);
+ auto q = tizen_base::Database::Sql(Q_INSERT)
+ .Bind("gogo")
+ .Bind(1234)
+ .Bind(9.216)
+ .Bind(std::vector<unsigned char> {'9', '2', '1', '6' });
+ auto r = db.Exec(q);
+ EXPECT_TRUE(static_cast<bool>(r));
+
+ q.Reset()
+ .Bind("gugu")
+ .Bind(5678)
+ .Bind(9.216)
+ .Bind(std::nullopt);
+ bool ret = db.Exec(q, r);
+ EXPECT_TRUE(ret);
+
+ q.Reset()
+ .Bind("gg")
+ .Bind(7777)
+ .Bind(9.216)
+ .Bind(std::nullopt);
+ ret = db.Exec(q, r);
+ EXPECT_TRUE(ret);
+}
+
TEST_F(DatabaseTest, test_select) {
SetDefault();
using tizen_base::_;
return query_;
}
+ Sql& Reset() {
+ bindings_.clear();
+ binding_map_.clear();
+ binding_name_map_.clear();
+ return *this;
+ }
+
private:
std::string query_;
std::vector<DbType> bindings_;
return std::nullopt;
}
+ sqlite3_stmt* GetRaw() const {
+ return stmt_;
+ }
+
+ const std::string& GetQuery() const {
+ return query_;
+ }
+
private:
friend class Database;
- Result(sqlite3_stmt* stmt, sqlite3* db) : stmt_(stmt), db_(db) {}
+ Result(sqlite3_stmt* stmt, sqlite3* db, std::string query)
+ : stmt_(stmt), db_(db), query_(std::move(query)) {}
sqlite3_stmt* stmt_ = nullptr;
sqlite3* db_ = nullptr;
+ std::string query_;
};
Database(std::string db, int flags) {
int r = sqlite3_prepare_v2(db_, sql.GetQuery().c_str(),
-1, &stmt, nullptr);
if (r != SQLITE_OK) {
- return { nullptr, nullptr };
+ return { nullptr, nullptr, "" };
}
std::unique_ptr<sqlite3_stmt, decltype(sqlite3_finalize)*> stmt_auto(stmt,
r = sqlite3_step(stmt);
if (r != SQLITE_ROW && r != SQLITE_DONE) {
- return { nullptr, db_ };
+ return { nullptr, db_, "" };
}
- return { stmt_auto.release(), db_ };
+ return { stmt_auto.release(), db_, sql.GetQuery() };
+ }
+
+ bool Exec(const Sql& sql, const Result& previous_stmt) {
+ if (sql.GetQuery() != previous_stmt.GetQuery())
+ throw std::runtime_error("Query is different");
+
+ sqlite3_stmt* stmt = previous_stmt.GetRaw();
+ if (!stmt)
+ return false;
+
+ int r = sqlite3_reset(stmt);
+ if (r != SQLITE_ROW && r != SQLITE_DONE && r != SQLITE_OK)
+ return false;
+
+ int pos = 1;
+ for (const auto& i : sql.GetBindings()) {
+ Bind(pos++, i, stmt);
+ }
+
+ for (const auto& i : sql.GetBindingMap()) {
+ Bind(i.first, i.second, stmt);
+ }
+
+ for (const auto& i : sql.GetBindingNameMap()) {
+ int pos = sqlite3_bind_parameter_index(stmt, i.first.c_str());
+ if (pos == 0)
+ throw std::runtime_error("Invalid binding");
+ Bind(pos, i.second, stmt);
+ }
+
+ r = sqlite3_step(stmt);
+ if (r != SQLITE_ROW && r != SQLITE_DONE)
+ return false;
+
+ return true;
}
private: