#include #include #include #include "Logger.h" #include bool db_exec(sqlite3* targetDB, const char* command) { char* errMsg = nullptr; int rc = sqlite3_exec(targetDB, command, 0, 0, &errMsg); if (rc != SQLITE_OK) { postLog("[SQLite] SQL error: " + std::string(errMsg), 4); sqlite3_free(errMsg); return false; } return true; } bool db_addItem(sqlite3* targetDB, std::string targetTable, int id, std::string sector, std::string value) { if (!targetDB) { postLog("[SQLite] targetDB is null.", 3); return false; } char* sql = nullptr; if (targetTable == "users") { sql = sqlite3_mprintf( "INSERT INTO users (userId, %Q) VALUES (%d, %Q);", sector.c_str(), id, value.c_str() ); } else if (targetTable == "salaryForm") { sql = sqlite3_mprintf( "INSERT INTO salaryForm (teacherId, %Q) VALUES (%d, %Q);", sector.c_str(), id, value.c_str() ); } else if (targetTable == "teacherInfo") { sql = sqlite3_mprintf( "INSERT INTO teacherInfo (teacherId, %Q) VALUES (%d, %Q);", sector.c_str(), id, value.c_str() ); } else { postLog("[SQLite] Unknown target table.", 3); return false; } if (!sql) { postLog("[SQLite] Failed to allocate SQL string.", 3); return false; } char* errMsg = nullptr; int rc = sqlite3_exec(targetDB, sql, 0, 0, &errMsg); sqlite3_free(sql); if (rc != SQLITE_OK) { postLog(std::string("[SQLite] Failed to add item: ") + (errMsg ? errMsg : "unknown error"), 3); if (errMsg) sqlite3_free(errMsg); return false; } return true; } bool db_updateItem(sqlite3* targetDB, std::string targetTable, int id, std::string sector, std::string value) { if (!targetDB) { postLog("[SQLite] targetDB is null.", 3); return false; } char* sql = nullptr; if (targetTable == "users"){ sql = sqlite3_mprintf( "UPDATE users SET %s=\'%s\' WHERE userId=%d;", sector.c_str(), value.c_str(), id ); } else if (targetTable == "salaryForm") { sql = sqlite3_mprintf( "UPDATE salaryForm SET %s=\'%s\' WHERE teacherId=%d;", sector.c_str(), value.c_str(), id ); } else if (targetTable == "teacherInfo") { sql = sqlite3_mprintf( "UPDATE teacherInfo SET %s=\'%s\' WHERE teacherId=%d;", sector.c_str(), value.c_str(), id ); } else { postLog("[SQLite] Unknown target table.", 3); return false; } if (!sql) { postLog("[SQLite] Failed to allocate SQL string.", 3); return false; } char* errMsg = nullptr; int rc = sqlite3_exec(targetDB, sql, 0, 0, &errMsg); sqlite3_free(sql); if (rc != SQLITE_OK) { postLog(std::string("[SQLite] Failed to add item: ") + (errMsg ? errMsg : "unknown error"), 3); if (errMsg) sqlite3_free(errMsg); return false; } return true; } bool db_rmItem(sqlite3* targetDB, std::string targetTable, int id) { if (!targetDB) { postLog("[SQLite] targetDB is null.", 3); return false; } char* sql = sqlite3_mprintf( "DELETE FROM %s WHERE teacherId = %d;", targetTable.c_str(), id ); if (!sql) { postLog("[SQLite] Failed to allocate SQL string.", 3); return false; } char* errMsg = nullptr; int rc = sqlite3_exec(targetDB, sql, 0, 0, &errMsg); sqlite3_free(sql); if (rc != SQLITE_OK) { postLog(std::string("[SQLite] Failed to remove item: ") + (errMsg ? errMsg : "unknown error"), 3); if (errMsg) sqlite3_free(errMsg); return false; } return true; } std::string db_getItem(sqlite3* sourceDB, std::string sourceTable, std::string itemType, int itemID) { if (!sourceDB) { postLog("[SQLite] sourceDB is null.", 3); return ""; } std::string command; if (sourceTable == "users") { command = "SELECT " + itemType + " FROM users WHERE userId = " + std::to_string(itemID) + ";"; } else if (sourceTable == "salaryForm") { command = "SELECT " + itemType + " FROM salaryForm WHERE teacherId = " + std::to_string(itemID) + ";"; } else if (sourceTable == "teacherInfo") { command = "SELECT " + itemType + " FROM teacherInfo WHERE teacherId = " + std::to_string(itemID) + ";"; } else { postLog("[SQLite] Unknown table in db_getItem.", 3); return ""; } sqlite3_stmt* stmt = nullptr; int rc = sqlite3_prepare_v2(sourceDB, command.c_str(), -1, &stmt, nullptr); if (rc != SQLITE_OK) { postLog(std::string("[SQLite] Precompiling failed: ") + sqlite3_errmsg(sourceDB), 3); if (stmt) sqlite3_finalize(stmt); return ""; } std::string result; rc = sqlite3_step(stmt); if (rc == SQLITE_ROW) { const unsigned char* txt = sqlite3_column_text(stmt, 0); if (txt) result = reinterpret_cast(txt); } else if (rc == SQLITE_DONE) { postLog("[SQLite] Failed to find specific ID [" + std::to_string(itemID) + "]", 3); result = "err: no specific id"; } else { postLog(std::string("[SQLite] Step error: ") + sqlite3_errmsg(sourceDB), 4); } sqlite3_finalize(stmt); return result; } std::string db_findIdBy(sqlite3* sourceDB, std::string sourceTable, std::string itemType, std::string value) { if (!sourceDB) { postLog("[SQLite] sourceDB is null.", 3); return "0"; } const std::string idCol = (sourceTable == "users") ? "userId" : "teacherId"; std::string sql = "SELECT " + idCol + " FROM " + sourceTable + " WHERE " + itemType + " = ?;"; sqlite3_stmt* stmt = nullptr; if (sqlite3_prepare_v2(sourceDB, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) { postLog(std::string("[SQLite] Precompiling failed: ") + sqlite3_errmsg(sourceDB), 3); return "0"; } // Bind the value: numeric vs text bool isNumber = !value.empty() && std::all_of(value.begin(), value.end(), [](unsigned char ch){ return std::isdigit(ch) != 0; }); if (isNumber) { sqlite3_bind_int(stmt, 1, std::stoi(value)); } else { sqlite3_bind_text(stmt, 1, value.c_str(), -1, SQLITE_TRANSIENT); } std::string result; int rc = sqlite3_step(stmt); if (rc == SQLITE_ROW) { const unsigned char* txt = sqlite3_column_text(stmt, 0); if (txt) result = reinterpret_cast(txt); } else if (rc == SQLITE_DONE) { postLog("[SQLite] Failed to find specific ID by content [" + itemType + ":" + value + "]", 3); result = "0"; } else { postLog(std::string("[SQLite] Step error: ") + sqlite3_errmsg(sourceDB), 4); } sqlite3_finalize(stmt); return result; }