#include "crow.h" #include "utils.hpp" #include "database.hpp" using namespace std; Database::Database() : m_db(nullptr) {} Database::~Database() { sqlite3_close(m_db); } sqlite3_stmt* Database::prepareStmt(const string& sql){ sqlite3_stmt* stmt = nullptr; if (sqlite3_prepare_v2(m_db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) { CROW_LOG_ERROR << "Failed to prepare statement: " << sqlite3_errmsg(m_db); return nullptr; } return stmt; } bool Database::exec(const char* sqlQuery) { char* errmsg = nullptr; int rc = sqlite3_exec(m_db, sqlQuery, nullptr, nullptr, &errmsg); if (rc != SQLITE_OK) { CROW_LOG_ERROR << "SQL error: " << errmsg; sqlite3_free(errmsg); return false; } return true; } bool Database::exec(const std::string& sqlQuery){ return exec(sqlQuery.c_str()); } map Database::getStrMap(const string& sql){ sqlite3_stmt* stmt = prepareStmt(sql); map map; if (stmt == nullptr) return map; while (sqlite3_step(stmt) == SQLITE_ROW) { string key = reinterpret_cast(sqlite3_column_text(stmt, 0)); string value = reinterpret_cast(sqlite3_column_text(stmt, 1)); map[key] = utils::urlDecode(value); } sqlite3_finalize(stmt); return map; } string Database::getStr(const string& sql){ sqlite3_stmt* stmt = prepareStmt(sql); string str; if (stmt == nullptr) return str; str = reinterpret_cast(sqlite3_column_text(stmt, 0)); sqlite3_finalize(stmt); return str; } set Database::getStrSet(const string& sql){ sqlite3_stmt* stmt = prepareStmt(sql); set vec; if (stmt == nullptr) return vec; while (sqlite3_step(stmt) == SQLITE_ROW) { string s = reinterpret_cast(sqlite3_column_text(stmt, 0)); vec.insert(s); } sqlite3_finalize(stmt); return vec; } std::optional Database::getInt(const char* sql) { sqlite3_stmt* stmt = prepareStmt(sql); if (stmt == nullptr) return {}; std::optional id; if (sqlite3_step(stmt) == SQLITE_ROW) { id = sqlite3_column_int64(stmt, 0); } sqlite3_finalize(stmt); return id; } std::optional Database::insert(const char* sql) { sqlite3_stmt* stmt = prepareStmt(sql); if (stmt == nullptr) return {}; if (sqlite3_step(stmt) != SQLITE_DONE) { CROW_LOG_ERROR << "Insert failed: " << sqlite3_errmsg(m_db); sqlite3_finalize(stmt); return {}; } sqlite3_finalize(stmt); return sqlite3_last_insert_rowid(m_db); } bool Database::open(){ int rc = sqlite3_open("app.db", &m_db); if (rc) { CROW_LOG_ERROR << "Can't open database: " << sqlite3_errmsg(m_db); return false; } return true; }