#include "SQLiteDatabase.h" void SQLiteDatabase::UpdateActivityLog(const LWOOBJID characterId, const eActivityType activityType, const LWOMAPID mapId) { ExecuteInsert("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);", characterId, static_cast(activityType), static_cast(time(NULL)), mapId); } std::vector SQLiteDatabase::GetRecentActivity(const uint32_t limit) { std::vector out; auto [stmt, res] = ExecuteSelect("SELECT character_id, activity, time, map_id FROM activity_log ORDER BY time DESC LIMIT ?;", limit); while (!res.eof()) { IActivityLog::Entry e; e.characterId = static_cast(res.getInt64Field("character_id")); e.activity = static_cast(res.getIntField("activity")); e.timestamp = static_cast(res.getIntField("time")); e.mapId = static_cast(res.getIntField("map_id")); out.push_back(e); res.nextRow(); } return out; } uint32_t SQLiteDatabase::GetActivityLogCount() { auto [_, res] = ExecuteSelect("SELECT COUNT(*) as count FROM activity_log;"); if (res.eof()) return 0; return res.getIntField("count"); } std::vector SQLiteDatabase::GetActivityLogPaginated( uint32_t offset, uint32_t limit, const std::string& orderColumn, const std::string& orderDir ) { std::vector out; // Validate orderColumn to prevent SQL injection std::string validColumn = "time"; if (orderColumn == "character_id" || orderColumn == "activity" || orderColumn == "map_id" || orderColumn == "time") { validColumn = orderColumn; } // Validate orderDir std::string validDir = (orderDir == "ASC" || orderDir == "asc") ? "ASC" : "DESC"; // Build query - can't use prepared statement for ORDER BY clause std::string query = "SELECT character_id, activity, time, map_id FROM activity_log ORDER BY " + validColumn + " " + validDir + " LIMIT ? OFFSET ?;"; auto [stmt, res] = ExecuteSelect(query, limit, offset); while (!res.eof()) { IActivityLog::Entry e; e.characterId = static_cast(res.getInt64Field("character_id")); e.activity = static_cast(res.getIntField("activity")); e.timestamp = static_cast(res.getIntField("time")); e.mapId = static_cast(res.getIntField("map_id")); out.push_back(e); res.nextRow(); } return out; }