#include "../../include/odhtdb/sql/SqlExec.hpp" #include "../../include/odhtdb/Log.hpp" #include namespace odhtdb { SqlExec::SqlExec(sqlite3 *_db, const char *sql) : db(_db), stmt(nullptr) { int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr); if(rc != SQLITE_OK) { std::string errMsg = "Failed to prepare sqlite statement, error: "; errMsg += sqlite3_errmsg(db); throw SqlExecException(errMsg); } } SqlExec::~SqlExec() { sqlite3_finalize(stmt); } void SqlExec::execWithArgs(std::initializer_list args) { std::lock_guard lock(mutex); sqlite3_reset(stmt); sqlite3_clear_bindings(stmt); int numParams = sqlite3_bind_parameter_count(stmt); if(args.size() != numParams) { std::string errMsg = "Failed to prepare sqlite statement, error: Sql has "; errMsg += std::to_string(numParams); errMsg += " parameters, got "; errMsg += std::to_string(args.size()); errMsg += " arguments"; throw SqlExecException(errMsg); } #ifdef ODHTDB_SQL_DEBUG Log::debug("Executing sql exec: %s; args(%u): ", sqlite3_sql(stmt), args.size()); usize i = 0; for(const SqlArg &arg : args) { Log::debug("arg(%u): %s", i, arg.toString().c_str()); ++i; } #endif int paramIndex = 1; for(const SqlArg &arg : args) { int rc = arg.bind(stmt, paramIndex); if(rc != SQLITE_OK) { std::string errMsg = "Failed to bind param, error code: "; errMsg += std::to_string(rc); throw SqlExecException(errMsg); } ++paramIndex; } int rc = sqlite3_step(stmt); if(rc != SQLITE_DONE) { std::string errMsg = "Failed to perform sql exec, error: "; errMsg += sqlite3_errmsg(db); throw SqlExecException(errMsg); } } void SqlExec::exec() { execWithArgs({}); } }