db: prepare marriage queries
This commit is contained in:
@@ -3,9 +3,177 @@
|
||||
#include "Main.h"
|
||||
#include "DBManager.h"
|
||||
#include "ClientManager.h"
|
||||
#include "libsql/Statement.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace marriage
|
||||
{
|
||||
namespace
|
||||
{
|
||||
struct MarriageRow
|
||||
{
|
||||
DWORD pid1 = 0;
|
||||
DWORD pid2 = 0;
|
||||
int lovePoint = 0;
|
||||
DWORD time = 0;
|
||||
BYTE isMarried = 0;
|
||||
char name1[CHARACTER_NAME_MAX_LEN + 1] = {};
|
||||
char name2[CHARACTER_NAME_MAX_LEN + 1] = {};
|
||||
};
|
||||
|
||||
bool PrepareMarriageStmt(CStmt& stmt, const std::string& query)
|
||||
{
|
||||
CAsyncSQL* sql = CDBManager::instance().GetDirectSQL(SQL_PLAYER);
|
||||
|
||||
if (!sql)
|
||||
{
|
||||
sys_err("player SQL handle is not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmt.Prepare(sql, query.c_str());
|
||||
}
|
||||
|
||||
bool PurgePendingMarriages()
|
||||
{
|
||||
CStmt stmt;
|
||||
const std::string query = "DELETE FROM marriage WHERE is_married = 0";
|
||||
|
||||
if (!PrepareMarriageStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
return stmt.Execute();
|
||||
}
|
||||
|
||||
bool LoadMarriageRows(std::vector<MarriageRow>& rows)
|
||||
{
|
||||
CStmt stmt;
|
||||
MarriageRow row = {};
|
||||
const std::string query = std::string("SELECT pid1, pid2, love_point, time, is_married, p1.name, p2.name FROM marriage, player")
|
||||
+ GetTablePostfix() + " as p1, player" + GetTablePostfix() + " as p2 WHERE p1.id = pid1 AND p2.id = pid2";
|
||||
|
||||
rows.clear();
|
||||
|
||||
if (!PrepareMarriageStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
if (!stmt.BindResult(MYSQL_TYPE_LONG, &row.pid1)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &row.pid2)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &row.lovePoint)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &row.time)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_TINY, &row.isMarried)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_STRING, row.name1, sizeof(row.name1))
|
||||
|| !stmt.BindResult(MYSQL_TYPE_STRING, row.name2, sizeof(row.name2)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!stmt.Execute())
|
||||
return false;
|
||||
|
||||
rows.reserve(stmt.iRows);
|
||||
|
||||
for (int i = 0; i < stmt.iRows; ++i)
|
||||
{
|
||||
row = {};
|
||||
|
||||
if (!stmt.Fetch())
|
||||
return false;
|
||||
|
||||
size_t name1Len = stmt.GetResultLength(5);
|
||||
if (name1Len >= sizeof(row.name1))
|
||||
name1Len = sizeof(row.name1) - 1;
|
||||
row.name1[name1Len] = '\0';
|
||||
|
||||
size_t name2Len = stmt.GetResultLength(6);
|
||||
if (name2Len >= sizeof(row.name2))
|
||||
name2Len = sizeof(row.name2) - 1;
|
||||
row.name2[name2Len] = '\0';
|
||||
|
||||
rows.push_back(row);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AddMarriageRow(DWORD pid1, DWORD pid2, DWORD time)
|
||||
{
|
||||
CStmt stmt;
|
||||
const std::string query = "INSERT INTO marriage(pid1, pid2, love_point, time) VALUES (?, ?, 0, ?)";
|
||||
|
||||
if (!PrepareMarriageStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
if (!stmt.BindParam(MYSQL_TYPE_LONG, &pid1)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &pid2)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &time)
|
||||
|| !stmt.Execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmt.GetAffectedRows() != 0 && stmt.GetAffectedRows() != static_cast<unsigned long long>(-1);
|
||||
}
|
||||
|
||||
bool UpdateMarriageRow(DWORD pid1, DWORD pid2, int lovePoint, BYTE isMarried)
|
||||
{
|
||||
CStmt stmt;
|
||||
const std::string query = "UPDATE marriage SET love_point = ?, is_married = ? WHERE pid1 = ? AND pid2 = ?";
|
||||
|
||||
if (!PrepareMarriageStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
if (!stmt.BindParam(MYSQL_TYPE_LONG, &lovePoint)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_TINY, &isMarried)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &pid1)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &pid2)
|
||||
|| !stmt.Execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmt.GetAffectedRows() != 0 && stmt.GetAffectedRows() != static_cast<unsigned long long>(-1);
|
||||
}
|
||||
|
||||
bool RemoveMarriageRow(DWORD pid1, DWORD pid2)
|
||||
{
|
||||
CStmt stmt;
|
||||
const std::string query = "DELETE FROM marriage WHERE pid1 = ? AND pid2 = ?";
|
||||
|
||||
if (!PrepareMarriageStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
if (!stmt.BindParam(MYSQL_TYPE_LONG, &pid1)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &pid2)
|
||||
|| !stmt.Execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmt.GetAffectedRows() != 0 && stmt.GetAffectedRows() != static_cast<unsigned long long>(-1);
|
||||
}
|
||||
|
||||
bool MarkMarriageAsMarried(DWORD pid1, DWORD pid2)
|
||||
{
|
||||
CStmt stmt;
|
||||
const std::string query = "UPDATE marriage SET is_married = 1 WHERE pid1 = ? AND pid2 = ?";
|
||||
|
||||
if (!PrepareMarriageStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
if (!stmt.BindParam(MYSQL_TYPE_LONG, &pid1)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &pid2)
|
||||
|| !stmt.Execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmt.GetAffectedRows() != 0 && stmt.GetAffectedRows() != static_cast<unsigned long long>(-1);
|
||||
}
|
||||
}
|
||||
|
||||
const DWORD WEDDING_LENGTH = 60 * 60; // sec
|
||||
bool operator < (const TWedding& lhs, const TWedding& rhs)
|
||||
{
|
||||
@@ -34,38 +202,29 @@ namespace marriage
|
||||
|
||||
bool CManager::Initialize()
|
||||
{
|
||||
char szQuery[1024];
|
||||
std::vector<MarriageRow> rows;
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"SELECT pid1, pid2, love_point, time, is_married, p1.name, p2.name FROM marriage, player%s as p1, player%s as p2 WHERE p1.id = pid1 AND p2.id = pid2",
|
||||
GetTablePostfix(), GetTablePostfix());
|
||||
if (!PurgePendingMarriages())
|
||||
sys_err("failed to purge pending marriages");
|
||||
|
||||
CDBManager::instance().DirectQuery("DELETE FROM marriage WHERE is_married = 0");
|
||||
|
||||
auto pmsg = CDBManager::instance().DirectQuery(szQuery);
|
||||
SQLResult * pRes = pmsg->Get();
|
||||
sys_log(0, "MarriageList(size=%lu)", pRes->uiNumRows);
|
||||
if (!LoadMarriageRows(rows))
|
||||
return false;
|
||||
|
||||
if (pRes->uiNumRows > 0)
|
||||
sys_log(0, "MarriageList(size=%lu)", rows.size());
|
||||
|
||||
if (!rows.empty())
|
||||
{
|
||||
for (uint uiRow = 0; uiRow != pRes->uiNumRows; ++uiRow)
|
||||
for (size_t uiRow = 0; uiRow != rows.size(); ++uiRow)
|
||||
{
|
||||
MYSQL_ROW row = mysql_fetch_row(pRes->pSQLResult);
|
||||
const auto& row = rows[uiRow];
|
||||
|
||||
DWORD pid1 = 0; str_to_number(pid1, row[0]);
|
||||
DWORD pid2 = 0; str_to_number(pid2, row[1]);
|
||||
int love_point = 0; str_to_number(love_point, row[2]);
|
||||
DWORD time = 0; str_to_number(time, row[3]);
|
||||
BYTE is_married = 0; str_to_number(is_married, row[4]);
|
||||
const char* name1 = row[5];
|
||||
const char* name2 = row[6];
|
||||
|
||||
TMarriage* pMarriage = new TMarriage(pid1, pid2, love_point, time, is_married, name1, name2);
|
||||
TMarriage* pMarriage = new TMarriage(row.pid1, row.pid2, row.lovePoint, row.time, row.isMarried, row.name1, row.name2);
|
||||
m_Marriages.insert(pMarriage);
|
||||
m_MarriageByPID.insert(make_pair(pid1, pMarriage));
|
||||
m_MarriageByPID.insert(make_pair(pid2, pMarriage));
|
||||
m_MarriageByPID.insert(make_pair(row.pid1, pMarriage));
|
||||
m_MarriageByPID.insert(make_pair(row.pid2, pMarriage));
|
||||
|
||||
sys_log(0, "Marriage %lu: LP:%d TM:%u ST:%d %10lu:%16s %10lu:%16s ", uiRow, love_point, time, is_married, pid1, name1, pid2, name2);
|
||||
sys_log(0, "Marriage %lu: LP:%d TM:%u ST:%d %10lu:%16s %10lu:%16s ",
|
||||
static_cast<unsigned long>(uiRow), row.lovePoint, row.time, row.isMarried, row.pid1, row.name1, row.pid2, row.name2);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -98,13 +257,7 @@ namespace marriage
|
||||
|
||||
Align(dwPID1, dwPID2);
|
||||
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery), "INSERT INTO marriage(pid1, pid2, love_point, time) VALUES (%u, %u, 0, %u)", dwPID1, dwPID2, now);
|
||||
|
||||
auto pmsg = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
SQLResult* res = pmsg->Get();
|
||||
if (res->uiAffectedRows == 0 || res->uiAffectedRows == (uint32_t)-1)
|
||||
if (!AddMarriageRow(dwPID1, dwPID2, now))
|
||||
{
|
||||
sys_err("cannot insert marriage");
|
||||
return;
|
||||
@@ -137,14 +290,7 @@ namespace marriage
|
||||
|
||||
Align(dwPID1, dwPID2);
|
||||
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery), "UPDATE marriage SET love_point = %d, is_married = %d WHERE pid1 = %u AND pid2 = %u",
|
||||
iLovePoint, byMarried, pMarriage->pid1, pMarriage->pid2);
|
||||
|
||||
auto pmsg = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
SQLResult* res = pmsg->Get();
|
||||
if (res->uiAffectedRows == 0 || res->uiAffectedRows == (uint32_t)-1)
|
||||
if (!UpdateMarriageRow(pMarriage->pid1, pMarriage->pid2, iLovePoint, byMarried))
|
||||
{
|
||||
sys_err("cannot update marriage : PID:%u %u", dwPID1, dwPID2);
|
||||
return;
|
||||
@@ -184,13 +330,7 @@ namespace marriage
|
||||
|
||||
Align(dwPID1, dwPID2);
|
||||
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery), "DELETE FROM marriage WHERE pid1 = %u AND pid2 = %u", dwPID1, dwPID2);
|
||||
|
||||
auto pmsg = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
SQLResult* res = pmsg->Get();
|
||||
if (res->uiAffectedRows == 0 || res->uiAffectedRows == (uint32_t)-1)
|
||||
if (!RemoveMarriageRow(dwPID1, dwPID2))
|
||||
{
|
||||
sys_err("cannot delete marriage : PID:%u %u", dwPID1, dwPID2);
|
||||
return;
|
||||
@@ -227,14 +367,7 @@ namespace marriage
|
||||
|
||||
Align(dwPID1, dwPID2);
|
||||
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery), "UPDATE marriage SET is_married = 1 WHERE pid1 = %u AND pid2 = %u",
|
||||
pMarriage->pid1, pMarriage->pid2);
|
||||
|
||||
auto pmsg = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
SQLResult* res = pmsg->Get();
|
||||
if (res->uiAffectedRows == 0 || res->uiAffectedRows == (uint32_t)-1)
|
||||
if (!MarkMarriageAsMarried(pMarriage->pid1, pMarriage->pid2))
|
||||
{
|
||||
sys_err("cannot change engage to marriage : PID:%u %u", dwPID1, dwPID2);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user