db: prepare boot refine and shop queries
This commit is contained in:
@@ -7,12 +7,39 @@
|
||||
|
||||
#include "CsvReader.h"
|
||||
#include "ProtoReader.h"
|
||||
#include "libsql/Statement.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern int g_test_server;
|
||||
extern std::string g_stLocaleNameColumn;
|
||||
|
||||
namespace
|
||||
{
|
||||
bool PrepareBootStmt(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());
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
void NullTerminateResult(char (&buffer)[N], unsigned long length)
|
||||
{
|
||||
size_t finalLength = length;
|
||||
if (finalLength >= N)
|
||||
finalLength = N - 1;
|
||||
|
||||
buffer[finalLength] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
bool CClientManager::InitializeTables()
|
||||
{
|
||||
if (!InitializeMobTable())
|
||||
@@ -97,16 +124,38 @@ bool CClientManager::InitializeTables()
|
||||
|
||||
bool CClientManager::InitializeRefineTable()
|
||||
{
|
||||
char query[2048];
|
||||
CStmt stmt;
|
||||
uint32_t id = 0;
|
||||
int32_t cost = 0;
|
||||
int32_t prob = 0;
|
||||
uint32_t materialVnums[REFINE_MATERIAL_MAX_NUM] = {};
|
||||
int32_t materialCounts[REFINE_MATERIAL_MAX_NUM] = {};
|
||||
const std::string query = std::string("SELECT id, cost, prob, vnum0, count0, vnum1, count1, vnum2, count2, vnum3, count3, vnum4, count4 FROM refine_proto")
|
||||
+ GetTablePostfix();
|
||||
|
||||
snprintf(query, sizeof(query),
|
||||
"SELECT id, cost, prob, vnum0, count0, vnum1, count1, vnum2, count2, vnum3, count3, vnum4, count4 FROM refine_proto%s",
|
||||
GetTablePostfix());
|
||||
if (!PrepareBootStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
auto pkMsg = CDBManager::instance().DirectQuery(query);
|
||||
SQLResult * pRes = pkMsg->Get();
|
||||
if (!stmt.BindResult(MYSQL_TYPE_LONG, &id)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &cost)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &prob))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pRes->uiNumRows)
|
||||
for (int i = 0; i < REFINE_MATERIAL_MAX_NUM; ++i)
|
||||
{
|
||||
if (!stmt.BindResult(MYSQL_TYPE_LONG, &materialVnums[i])
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &materialCounts[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stmt.Execute())
|
||||
return false;
|
||||
|
||||
if (!stmt.iRows)
|
||||
return true;
|
||||
|
||||
if (m_pRefineTable)
|
||||
@@ -116,30 +165,27 @@ bool CClientManager::InitializeRefineTable()
|
||||
m_pRefineTable = NULL;
|
||||
}
|
||||
|
||||
m_iRefineTableSize = pRes->uiNumRows;
|
||||
m_iRefineTableSize = stmt.iRows;
|
||||
|
||||
m_pRefineTable = new TRefineTable[m_iRefineTableSize];
|
||||
memset(m_pRefineTable, 0, sizeof(TRefineTable) * m_iRefineTableSize);
|
||||
|
||||
TRefineTable* prt = m_pRefineTable;
|
||||
MYSQL_ROW data;
|
||||
|
||||
while ((data = mysql_fetch_row(pRes->pSQLResult)))
|
||||
for (int row = 0; row < stmt.iRows; ++row)
|
||||
{
|
||||
//const char* s_szQuery = "SELECT src_vnum, result_vnum, cost, prob, "
|
||||
//"vnum0, count0, vnum1, count1, vnum2, count2, vnum3, count3, vnum4, count4 "
|
||||
if (!stmt.Fetch())
|
||||
return false;
|
||||
|
||||
int col = 0;
|
||||
//prt->src_vnum = atoi(data[col++]);
|
||||
//prt->result_vnum = atoi(data[col++]);
|
||||
str_to_number(prt->id, data[col++]);
|
||||
str_to_number(prt->cost, data[col++]);
|
||||
str_to_number(prt->prob, data[col++]);
|
||||
prt->id = id;
|
||||
prt->cost = cost;
|
||||
prt->prob = prob;
|
||||
prt->material_count = REFINE_MATERIAL_MAX_NUM;
|
||||
|
||||
for (int i = 0; i < REFINE_MATERIAL_MAX_NUM; i++)
|
||||
{
|
||||
str_to_number(prt->materials[i].vnum, data[col++]);
|
||||
str_to_number(prt->materials[i].count, data[col++]);
|
||||
prt->materials[i].vnum = materialVnums[i];
|
||||
prt->materials[i].count = materialCounts[i];
|
||||
if (prt->materials[i].vnum == 0)
|
||||
{
|
||||
prt->material_count = i;
|
||||
@@ -429,25 +475,31 @@ bool CClientManager::InitializeMobTable()
|
||||
|
||||
bool CClientManager::InitializeShopTable()
|
||||
{
|
||||
MYSQL_ROW data;
|
||||
int col;
|
||||
|
||||
static const char * s_szQuery =
|
||||
CStmt stmt;
|
||||
uint32_t shopVnum = 0;
|
||||
uint32_t npcVnum = 0;
|
||||
uint32_t itemVnum = 0;
|
||||
uint32_t itemCount = 0;
|
||||
const char* query =
|
||||
"SELECT "
|
||||
"shop.vnum, "
|
||||
"shop.npc_vnum, "
|
||||
"shop_item.item_vnum, "
|
||||
"shop_item.count "
|
||||
"COALESCE(shop_item.item_vnum, 0), "
|
||||
"COALESCE(shop_item.count, 0) "
|
||||
"FROM shop LEFT JOIN shop_item "
|
||||
"ON shop.vnum = shop_item.shop_vnum ORDER BY shop.vnum, shop_item.item_vnum";
|
||||
|
||||
auto pkMsg2 = CDBManager::instance().DirectQuery(s_szQuery);
|
||||
if (!PrepareBootStmt(stmt, query)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &shopVnum)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &npcVnum)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &itemVnum)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &itemCount)
|
||||
|| !stmt.Execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// shop의 vnum은 있는데 shop_item 이 없을경우... 실패로 처리되니 주의 요망.
|
||||
// 고처야할부분
|
||||
SQLResult * pRes2 = pkMsg2->Get();
|
||||
|
||||
if (!pRes2->uiNumRows)
|
||||
if (!stmt.iRows)
|
||||
{
|
||||
sys_err("InitializeShopTable : Table count is zero.");
|
||||
return false;
|
||||
@@ -463,12 +515,12 @@ bool CClientManager::InitializeShopTable()
|
||||
|
||||
TShopTable * shop_table = m_pShopTable;
|
||||
|
||||
while ((data = mysql_fetch_row(pRes2->pSQLResult)))
|
||||
for (int row = 0; row < stmt.iRows; ++row)
|
||||
{
|
||||
col = 0;
|
||||
if (!stmt.Fetch())
|
||||
return false;
|
||||
|
||||
int iShopVnum = 0;
|
||||
str_to_number(iShopVnum, data[col++]);
|
||||
int iShopVnum = static_cast<int>(shopVnum);
|
||||
|
||||
if (map_shop.end() == map_shop.find(iShopVnum))
|
||||
{
|
||||
@@ -481,15 +533,15 @@ bool CClientManager::InitializeShopTable()
|
||||
else
|
||||
shop_table = map_shop[iShopVnum];
|
||||
|
||||
str_to_number(shop_table->dwNPCVnum, data[col++]);
|
||||
shop_table->dwNPCVnum = npcVnum;
|
||||
|
||||
if (!data[col]) // 아이템이 하나도 없으면 NULL이 리턴 되므로..
|
||||
if (!itemVnum)
|
||||
continue;
|
||||
|
||||
TShopItemTable * pItem = &shop_table->items[shop_table->byItemCount];
|
||||
|
||||
str_to_number(pItem->vnum, data[col++]);
|
||||
str_to_number(pItem->count, data[col++]);
|
||||
pItem->vnum = itemVnum;
|
||||
pItem->count = static_cast<uint8_t>(itemCount);
|
||||
|
||||
++shop_table->byItemCount;
|
||||
}
|
||||
@@ -515,40 +567,42 @@ bool CClientManager::InitializeQuestItemTable()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
static const char * s_szQuery = "SELECT vnum, name, %s FROM quest_item_proto ORDER BY vnum";
|
||||
|
||||
char query[1024];
|
||||
snprintf(query, sizeof(query), s_szQuery, g_stLocaleNameColumn.c_str());
|
||||
snprintf(query, sizeof(query), "SELECT vnum, COALESCE(name, ''), COALESCE(%s, '') FROM quest_item_proto ORDER BY vnum", g_stLocaleNameColumn.c_str());
|
||||
|
||||
auto pkMsg = CDBManager::instance().DirectQuery(query);
|
||||
SQLResult * pRes = pkMsg->Get();
|
||||
CStmt stmt;
|
||||
uint32_t vnum = 0;
|
||||
char name[ITEM_NAME_MAX_LEN + 1] = {};
|
||||
char localeName[ITEM_NAME_MAX_LEN + 1] = {};
|
||||
|
||||
if (!pRes->uiNumRows)
|
||||
if (!PrepareBootStmt(stmt, query)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &vnum)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_STRING, name, sizeof(name))
|
||||
|| !stmt.BindResult(MYSQL_TYPE_STRING, localeName, sizeof(localeName))
|
||||
|| !stmt.Execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!stmt.iRows)
|
||||
{
|
||||
sys_err("query error or no rows: %s", query);
|
||||
return false;
|
||||
}
|
||||
|
||||
MYSQL_ROW row;
|
||||
|
||||
while ((row = mysql_fetch_row(pRes->pSQLResult)))
|
||||
for (int row = 0; row < stmt.iRows; ++row)
|
||||
{
|
||||
int col = 0;
|
||||
if (!stmt.Fetch())
|
||||
return false;
|
||||
|
||||
TItemTable tbl;
|
||||
memset(&tbl, 0, sizeof(tbl));
|
||||
|
||||
str_to_number(tbl.dwVnum, row[col++]);
|
||||
|
||||
if (row[col])
|
||||
strlcpy(tbl.szName, row[col], sizeof(tbl.szName));
|
||||
|
||||
col++;
|
||||
|
||||
if (row[col])
|
||||
strlcpy(tbl.szLocaleName, row[col], sizeof(tbl.szLocaleName));
|
||||
|
||||
col++;
|
||||
NullTerminateResult(name, stmt.GetResultLength(1));
|
||||
NullTerminateResult(localeName, stmt.GetResultLength(2));
|
||||
tbl.dwVnum = vnum;
|
||||
strlcpy(tbl.szName, name, sizeof(tbl.szName));
|
||||
strlcpy(tbl.szLocaleName, localeName, sizeof(tbl.szLocaleName));
|
||||
|
||||
if (m_map_itemTableByVnum.find(tbl.dwVnum) != m_map_itemTableByVnum.end())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user