#include "MySQLDatabase.h" #include "GeneralUtils.h" #include "MailSql.h" void MySQLDatabase::InsertNewMail(const MailInfo& mail) { ExecuteInsert( "INSERT INTO `mail` " "(`sender_id`, `sender_name`, `receiver_id`, `receiver_name`, `time_sent`, `subject`, `body`, `attachment_id`, `attachment_lot`, `attachment_subkey`, `attachment_count`, `attachment_config`, `was_read`)" " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,0)", mail.senderId, mail.senderUsername, mail.receiverId, mail.recipient, static_cast(time(NULL)), mail.subject, mail.body, mail.itemID, mail.itemLOT, mail.itemSubkey, mail.itemCount, mail.itemConfig); } std::vector MySQLDatabase::GetMailForPlayer(const LWOOBJID characterId, const uint32_t numberOfMail) { auto res = ExecuteSelect( "SELECT id, subject, body, sender_name, attachment_id, attachment_lot, attachment_subkey, attachment_count, was_read, time_sent" " FROM mail WHERE receiver_id=? AND deleted_at=0 limit ?;", characterId, numberOfMail); std::vector toReturn; toReturn.reserve(res->rowsCount()); while (res->next()) { MailInfo mail; mail.id = res->getUInt64("id"); mail.subject = res->getString("subject").c_str(); mail.body = res->getString("body").c_str(); mail.senderUsername = res->getString("sender_name").c_str(); mail.itemID = res->getInt64("attachment_id"); mail.itemLOT = res->getInt("attachment_lot"); mail.itemSubkey = res->getInt64("attachment_subkey"); mail.itemCount = res->getInt("attachment_count"); mail.timeSent = res->getUInt64("time_sent"); mail.wasRead = res->getBoolean("was_read"); toReturn.push_back(std::move(mail)); } return toReturn; } std::optional MySQLDatabase::GetMail(const uint64_t mailId) { auto res = ExecuteSelect("SELECT sender_id, attachment_id, attachment_lot, attachment_subkey, attachment_count, attachment_config, receiver_id FROM mail WHERE id=? AND deleted_at=0 LIMIT 1;", mailId); if (!res->next()) { return std::nullopt; } MailInfo toReturn; toReturn.id = mailId; toReturn.senderId = res->getInt64("sender_id"); toReturn.itemID = res->getInt64("attachment_id"); toReturn.itemLOT = res->getInt("attachment_lot"); toReturn.itemSubkey = res->getInt64("attachment_subkey"); toReturn.itemCount = res->getInt("attachment_count"); toReturn.itemConfig = res->isNull("attachment_config") ? "" : std::string(res->getString("attachment_config").c_str()); toReturn.receiverId = res->getUInt64("receiver_id"); return toReturn; } uint32_t MySQLDatabase::GetUnreadMailCount(const LWOOBJID characterId) { auto res = ExecuteSelect("SELECT COUNT(*) AS number_unread FROM mail WHERE receiver_id=? AND was_read=0 AND deleted_at=0;", characterId); if (!res->next()) { return 0; } return res->getInt("number_unread"); } void MySQLDatabase::MarkMailRead(const uint64_t mailId) { ExecuteUpdate("UPDATE mail SET was_read=1 WHERE id=? LIMIT 1;", mailId); } void MySQLDatabase::ClaimMailItem(const uint64_t mailId) { ExecuteUpdate("UPDATE mail SET attachment_lot=0 WHERE id=? LIMIT 1;", mailId); } void MySQLDatabase::DeleteMail(const uint64_t mailId) { // Kept for staff (the dashboard shows it as deleted); every read for the game skips it ExecuteUpdate("UPDATE mail SET deleted_at=? WHERE id=? AND deleted_at=0 LIMIT 1;", static_cast(time(NULL)), mailId); } std::vector MySQLDatabase::GetMailHistory(const MailQuery& q) { const auto pattern = GeneralUtils::LikeEscape(q.search, '!'); auto res = ExecuteSelect(MailSql::Select() + MailSql::Where(q, "CONCAT('%', ?, '%')") + " ORDER BY m.id DESC LIMIT ? OFFSET ?;", q.characterId, q.characterId, q.characterId, q.accountId, q.accountId, q.accountId, q.search, pattern, pattern, pattern, pattern, q.limit, q.offset); std::vector rows; while (res->next()) { rows.push_back({ res->getUInt64("id"), res->getInt64("sender_id"), std::string(res->getString("sender_name").c_str()), res->getUInt("sender_account"), res->getInt64("receiver_id"), std::string(res->getString("receiver_name").c_str()), res->getUInt("receiver_account"), res->getInt64("time_sent"), std::string(res->getString("subject").c_str()), std::string(res->getString("body").c_str()), res->getInt64("attachment_id"), res->getInt("attachment_lot"), res->getInt64("attachment_subkey"), res->getInt("attachment_count"), res->isNull("attachment_config") ? "" : std::string(res->getString("attachment_config").c_str()), res->getBoolean("was_read"), res->getInt64("deleted_at") }); } return rows; } uint64_t MySQLDatabase::CountMailHistory(const MailQuery& q) { const auto pattern = GeneralUtils::LikeEscape(q.search, '!'); auto res = ExecuteSelect("SELECT COUNT(*) AS count FROM mail AS m" + MailSql::Where(q, "CONCAT('%', ?, '%')") + ";", q.characterId, q.characterId, q.characterId, q.accountId, q.accountId, q.accountId, q.search, pattern, pattern, pattern, pattern); return res->next() ? res->getUInt64("count") : 0; }