db: prepare guild and rename queries
This commit is contained in:
@@ -7,12 +7,62 @@
|
|||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "QID.h"
|
#include "QID.h"
|
||||||
#include "Cache.h"
|
#include "Cache.h"
|
||||||
|
#include "libsql/Statement.h"
|
||||||
|
|
||||||
extern std::string g_stLocale;
|
extern std::string g_stLocale;
|
||||||
extern bool CreatePlayerTableFromRes(MYSQL_RES * res, TPlayerTable * pkTab);
|
extern bool CreatePlayerTableFromRes(MYSQL_RES * res, TPlayerTable * pkTab);
|
||||||
extern int g_test_server;
|
extern int g_test_server;
|
||||||
extern int g_log;
|
extern int g_log;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
bool CountPlayersByNameExcludingId(const char* player_name, DWORD player_id, unsigned long long* count)
|
||||||
|
{
|
||||||
|
char query[QUERY_MAX_LEN];
|
||||||
|
|
||||||
|
if (g_stLocale == "sjis")
|
||||||
|
snprintf(query, sizeof(query), "SELECT COUNT(*) FROM player%s WHERE name = ? COLLATE sjis_japanese_ci AND id <> ?", GetTablePostfix());
|
||||||
|
else
|
||||||
|
snprintf(query, sizeof(query), "SELECT COUNT(*) FROM player%s WHERE name = ? AND id <> ?", GetTablePostfix());
|
||||||
|
|
||||||
|
CStmt stmt;
|
||||||
|
if (!stmt.Prepare(CDBManager::instance().GetDirectSQL(SQL_PLAYER), query))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stmt.BindParam(MYSQL_TYPE_STRING, (void*) player_name, CHARACTER_NAME_MAX_LEN))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stmt.BindParam(MYSQL_TYPE_LONG, &player_id))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stmt.BindResult(MYSQL_TYPE_LONGLONG, count))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stmt.Execute() || !stmt.Fetch())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UpdatePlayerName(DWORD player_id, const char* player_name)
|
||||||
|
{
|
||||||
|
char query[QUERY_MAX_LEN];
|
||||||
|
snprintf(query, sizeof(query), "UPDATE player%s SET name = ?, change_name = 0 WHERE id = ?", GetTablePostfix());
|
||||||
|
|
||||||
|
CStmt stmt;
|
||||||
|
if (!stmt.Prepare(CDBManager::instance().GetDirectSQL(SQL_PLAYER), query))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stmt.BindParam(MYSQL_TYPE_STRING, (void*) player_name, CHARACTER_NAME_MAX_LEN))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stmt.BindParam(MYSQL_TYPE_LONG, &player_id))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return stmt.Execute() != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool CClientManager::InsertLogonAccount(const char * c_pszLogin, DWORD dwHandle, const char * c_pszIP)
|
bool CClientManager::InsertLogonAccount(const char * c_pszLogin, DWORD dwHandle, const char * c_pszIP)
|
||||||
{
|
{
|
||||||
char szLogin[LOGIN_MAX_LEN + 1];
|
char szLogin[LOGIN_MAX_LEN + 1];
|
||||||
@@ -464,44 +514,24 @@ void CClientManager::QUERY_LOGOUT(CPeer * peer, DWORD dwHandle,const char * data
|
|||||||
|
|
||||||
void CClientManager::QUERY_CHANGE_NAME(CPeer * peer, DWORD dwHandle, TPacketGDChangeName * p)
|
void CClientManager::QUERY_CHANGE_NAME(CPeer * peer, DWORD dwHandle, TPacketGDChangeName * p)
|
||||||
{
|
{
|
||||||
char queryStr[QUERY_MAX_LEN];
|
unsigned long long count = 0;
|
||||||
|
if (!CountPlayersByNameExcludingId(p->name, p->pid, &count))
|
||||||
if (g_stLocale == "sjis")
|
|
||||||
snprintf(queryStr, sizeof(queryStr),
|
|
||||||
"SELECT COUNT(*) as count FROM player%s WHERE name='%s' collate sjis_japanese_ci AND id <> %u",
|
|
||||||
GetTablePostfix(), p->name, p->pid);
|
|
||||||
else
|
|
||||||
snprintf(queryStr, sizeof(queryStr),
|
|
||||||
"SELECT COUNT(*) as count FROM player%s WHERE name='%s' AND id <> %u", GetTablePostfix(), p->name, p->pid);
|
|
||||||
|
|
||||||
auto pMsg = CDBManager::instance().DirectQuery(queryStr, SQL_PLAYER);
|
|
||||||
|
|
||||||
if (pMsg->Get()->uiNumRows)
|
|
||||||
{
|
|
||||||
if (!pMsg->Get()->pSQLResult)
|
|
||||||
{
|
|
||||||
peer->EncodeHeader(DG::PLAYER_CREATE_FAILED, dwHandle, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
|
|
||||||
|
|
||||||
if (*row[0] != '0')
|
|
||||||
{
|
|
||||||
peer->EncodeHeader(DG::PLAYER_CREATE_ALREADY, dwHandle, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
peer->EncodeHeader(DG::PLAYER_CREATE_FAILED, dwHandle, 0);
|
peer->EncodeHeader(DG::PLAYER_CREATE_FAILED, dwHandle, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(queryStr, sizeof(queryStr),
|
if (count != 0)
|
||||||
"UPDATE player%s SET name='%s',change_name=0 WHERE id=%u", GetTablePostfix(), p->name, p->pid);
|
{
|
||||||
|
peer->EncodeHeader(DG::PLAYER_CREATE_ALREADY, dwHandle, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto pMsg0 = CDBManager::instance().DirectQuery(queryStr, SQL_PLAYER);
|
if (!UpdatePlayerName(p->pid, p->name))
|
||||||
|
{
|
||||||
|
peer->EncodeHeader(DG::PLAYER_CREATE_FAILED, dwHandle, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TPacketDGChangeName pdg;
|
TPacketDGChangeName pdg;
|
||||||
peer->EncodeHeader(DG::CHANGE_NAME, dwHandle, sizeof(TPacketDGChangeName));
|
peer->EncodeHeader(DG::CHANGE_NAME, dwHandle, sizeof(TPacketDGChangeName));
|
||||||
@@ -509,4 +539,3 @@ void CClientManager::QUERY_CHANGE_NAME(CPeer * peer, DWORD dwHandle, TPacketGDCh
|
|||||||
strlcpy(pdg.name, p->name, sizeof(pdg.name));
|
strlcpy(pdg.name, p->name, sizeof(pdg.name));
|
||||||
peer->Encode(&pdg, sizeof(TPacketDGChangeName));
|
peer->Encode(&pdg, sizeof(TPacketDGChangeName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ class CDBManager : public singleton<CDBManager>
|
|||||||
void ReturnQuery(const char * c_pszQuery, int iType, IDENT dwIdent, void * pvData, int iSlot = SQL_PLAYER);
|
void ReturnQuery(const char * c_pszQuery, int iType, IDENT dwIdent, void * pvData, int iSlot = SQL_PLAYER);
|
||||||
void AsyncQuery(const char * c_pszQuery, int iSlot = SQL_PLAYER);
|
void AsyncQuery(const char * c_pszQuery, int iSlot = SQL_PLAYER);
|
||||||
std::unique_ptr<SQLMsg> DirectQuery(const char* c_pszQuery, int iSlot = SQL_PLAYER);
|
std::unique_ptr<SQLMsg> DirectQuery(const char* c_pszQuery, int iSlot = SQL_PLAYER);
|
||||||
|
CAsyncSQL* GetDirectSQL(int iSlot = SQL_PLAYER) { return m_directSQL[iSlot].get(); }
|
||||||
|
|
||||||
SQLMsg * PopResult();
|
SQLMsg * PopResult();
|
||||||
SQLMsg * PopResult(eSQL_SLOT slot );
|
SQLMsg * PopResult(eSQL_SLOT slot );
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ class DBManager : public singleton<DBManager>
|
|||||||
|
|
||||||
std::unique_ptr<SQLMsg> DirectQuery(const char* c_pszFormat, ...);
|
std::unique_ptr<SQLMsg> DirectQuery(const char* c_pszFormat, ...);
|
||||||
void ReturnQuery(int iType, DWORD dwIdent, void* pvData, const char * c_pszFormat, ...);
|
void ReturnQuery(int iType, DWORD dwIdent, void* pvData, const char * c_pszFormat, ...);
|
||||||
|
CAsyncSQL* GetDirectSQL() { return &m_sql_direct; }
|
||||||
|
|
||||||
void Process();
|
void Process();
|
||||||
void AnalyzeReturnQuery(SQLMsg * pmsg);
|
void AnalyzeReturnQuery(SQLMsg * pmsg);
|
||||||
|
|||||||
@@ -15,9 +15,30 @@
|
|||||||
#include "locale_service.h"
|
#include "locale_service.h"
|
||||||
#include "guild_manager.h"
|
#include "guild_manager.h"
|
||||||
#include "MarkManager.h"
|
#include "MarkManager.h"
|
||||||
|
#include "libsql/Statement.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
bool CountGuildsByName(const char* guild_name, unsigned long long* count)
|
||||||
|
{
|
||||||
|
char query[256];
|
||||||
|
snprintf(query, sizeof(query), "SELECT COUNT(*) FROM guild%s WHERE name = ?", get_table_postfix());
|
||||||
|
|
||||||
|
CStmt stmt;
|
||||||
|
if (!stmt.Prepare(DBManager::instance().GetDirectSQL(), query))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stmt.BindParam(MYSQL_TYPE_STRING, (void*) guild_name, GUILD_NAME_MAX_LEN))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stmt.BindResult(MYSQL_TYPE_LONGLONG, count))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stmt.Execute() || !stmt.Fetch())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
struct FGuildNameSender
|
struct FGuildNameSender
|
||||||
{
|
{
|
||||||
@@ -81,25 +102,19 @@ DWORD CGuildManager::CreateGuild(TGuildCreateParameter& gcp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pmsg = DBManager::instance().DirectQuery("SELECT COUNT(*) FROM guild%s WHERE name = '%s'",
|
unsigned long long guild_count = 0;
|
||||||
get_table_postfix(), gcp.name);
|
if (!CountGuildsByName(gcp.name, &guild_count))
|
||||||
|
|
||||||
if (pmsg->Get()->uiNumRows > 0)
|
|
||||||
{
|
|
||||||
MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
|
|
||||||
|
|
||||||
if (!(row[0] && row[0][0] == '0'))
|
|
||||||
{
|
|
||||||
gcp.master->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 이미 같은 이름의 길드가 있습니다."));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
gcp.master->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 길드를 생성할 수 없습니다."));
|
gcp.master->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 길드를 생성할 수 없습니다."));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (guild_count != 0)
|
||||||
|
{
|
||||||
|
gcp.master->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 이미 같은 이름의 길드가 있습니다."));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// new CGuild(gcp) queries guild tables and tell dbcache to notice other game servers.
|
// new CGuild(gcp) queries guild tables and tell dbcache to notice other game servers.
|
||||||
// other game server calls CGuildManager::LoadGuild to load guild.
|
// other game server calls CGuildManager::LoadGuild to load guild.
|
||||||
CGuild * pg = M2_NEW CGuild(gcp);
|
CGuild * pg = M2_NEW CGuild(gcp);
|
||||||
@@ -956,4 +971,3 @@ void CGuildManager::ChangeMaster(DWORD dwGID)
|
|||||||
"SELECT 1");
|
"SELECT 1");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "unique_item.h"
|
#include "unique_item.h"
|
||||||
#include "mob_manager.h"
|
#include "mob_manager.h"
|
||||||
|
#include "libsql/Statement.h"
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
|
||||||
#undef sys_err
|
#undef sys_err
|
||||||
@@ -33,6 +34,48 @@ const int ITEM_BROKEN_METIN_VNUM = 28960;
|
|||||||
|
|
||||||
namespace quest
|
namespace quest
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
bool CountPlayersByName(const char* player_name, unsigned long long* count)
|
||||||
|
{
|
||||||
|
char query[256];
|
||||||
|
snprintf(query, sizeof(query), "SELECT COUNT(*) FROM player%s WHERE name = ?", get_table_postfix());
|
||||||
|
|
||||||
|
CStmt stmt;
|
||||||
|
if (!stmt.Prepare(DBManager::instance().GetDirectSQL(), query))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stmt.BindParam(MYSQL_TYPE_STRING, (void*) player_name, CHARACTER_NAME_MAX_LEN))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stmt.BindResult(MYSQL_TYPE_LONGLONG, count))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stmt.Execute() || !stmt.Fetch())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UpdatePlayerName(DWORD player_id, const char* player_name)
|
||||||
|
{
|
||||||
|
char query[256];
|
||||||
|
snprintf(query, sizeof(query), "UPDATE player%s SET name = ?, change_name = 0 WHERE id = ?", get_table_postfix());
|
||||||
|
|
||||||
|
CStmt stmt;
|
||||||
|
if (!stmt.Prepare(DBManager::instance().GetDirectSQL(), query))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stmt.BindParam(MYSQL_TYPE_STRING, (void*) player_name, CHARACTER_NAME_MAX_LEN))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!stmt.BindParam(MYSQL_TYPE_LONG, &player_id))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return stmt.Execute() != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// "pc" Lua functions
|
// "pc" Lua functions
|
||||||
//
|
//
|
||||||
@@ -2114,23 +2157,18 @@ teleport_area:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char szQuery[1024];
|
unsigned long long count = 0;
|
||||||
snprintf(szQuery, sizeof(szQuery), "SELECT COUNT(*) FROM player%s WHERE name='%s'", get_table_postfix(), szName);
|
if (!CountPlayersByName(szName, &count))
|
||||||
auto pmsg = DBManager::instance().DirectQuery(szQuery);
|
|
||||||
|
|
||||||
if ( pmsg->Get()->uiNumRows > 0 )
|
|
||||||
{
|
{
|
||||||
MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
|
lua_pushnumber(L, 5);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int count = 0;
|
// 이미 해당 이름을 가진 캐릭터가 있음
|
||||||
str_to_number(count, row[0]);
|
if (count != 0)
|
||||||
|
{
|
||||||
// 이미 해당 이름을 가진 캐릭터가 있음
|
lua_pushnumber(L, 3);
|
||||||
if ( count != 0 )
|
return 1;
|
||||||
{
|
|
||||||
lua_pushnumber(L, 3);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD pid = ch->GetPlayerID();
|
DWORD pid = ch->GetPlayerID();
|
||||||
@@ -2144,8 +2182,11 @@ teleport_area:
|
|||||||
/* change_name_log */
|
/* change_name_log */
|
||||||
LogManager::instance().ChangeNameLog(pid, ch->GetName(), szName, ch->GetDesc()->GetHostName());
|
LogManager::instance().ChangeNameLog(pid, ch->GetName(), szName, ch->GetDesc()->GetHostName());
|
||||||
|
|
||||||
snprintf(szQuery, sizeof(szQuery), "UPDATE player%s SET name='%s' WHERE id=%u", get_table_postfix(), szName, pid);
|
if (!UpdatePlayerName(pid, szName))
|
||||||
DBManager::instance().DirectQuery(szQuery);
|
{
|
||||||
|
lua_pushnumber(L, 5);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
ch->SetNewName(szName);
|
ch->SetNewName(szName);
|
||||||
lua_pushnumber(L, 4);
|
lua_pushnumber(L, 4);
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ CStmt::CStmt()
|
|||||||
m_uiParamCount = 0;
|
m_uiParamCount = 0;
|
||||||
m_uiResultCount = 0;
|
m_uiResultCount = 0;
|
||||||
iRows = 0;
|
iRows = 0;
|
||||||
m_puiParamLen = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CStmt::~CStmt()
|
CStmt::~CStmt()
|
||||||
@@ -25,11 +24,13 @@ void CStmt::Destroy()
|
|||||||
m_pkStmt = NULL;
|
m_pkStmt = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_puiParamLen)
|
m_vec_param.clear();
|
||||||
{
|
m_vecParamLen.clear();
|
||||||
free(m_puiParamLen);
|
m_vec_result.clear();
|
||||||
m_puiParamLen = NULL;
|
m_vecResultLen.clear();
|
||||||
}
|
m_uiParamCount = 0;
|
||||||
|
m_uiResultCount = 0;
|
||||||
|
iRows = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStmt::Error(const char * c_pszMsg)
|
void CStmt::Error(const char * c_pszMsg)
|
||||||
@@ -39,6 +40,7 @@ void CStmt::Error(const char * c_pszMsg)
|
|||||||
|
|
||||||
bool CStmt::Prepare(CAsyncSQL * sql, const char * c_pszQuery)
|
bool CStmt::Prepare(CAsyncSQL * sql, const char * c_pszQuery)
|
||||||
{
|
{
|
||||||
|
Destroy();
|
||||||
m_pkStmt = mysql_stmt_init(sql->GetSQLHandle());
|
m_pkStmt = mysql_stmt_init(sql->GetSQLHandle());
|
||||||
m_stQuery = c_pszQuery;
|
m_stQuery = c_pszQuery;
|
||||||
|
|
||||||
@@ -48,27 +50,20 @@ bool CStmt::Prepare(CAsyncSQL * sql, const char * c_pszQuery)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iParamCount = 0;
|
const unsigned int param_count = mysql_stmt_param_count(m_pkStmt);
|
||||||
|
if (param_count)
|
||||||
for (unsigned int i = 0; i < m_stQuery.length(); ++i)
|
|
||||||
if (c_pszQuery[i] == '?')
|
|
||||||
++iParamCount;
|
|
||||||
|
|
||||||
if (iParamCount)
|
|
||||||
{
|
{
|
||||||
m_vec_param.resize(iParamCount);
|
m_vec_param.resize(param_count);
|
||||||
memset(&m_vec_param[0], 0, sizeof(MYSQL_BIND) * iParamCount);
|
memset(&m_vec_param[0], 0, sizeof(MYSQL_BIND) * param_count);
|
||||||
|
m_vecParamLen.resize(param_count, 0);
|
||||||
m_puiParamLen = (long unsigned int *) calloc(iParamCount, sizeof(long unsigned int));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vec_result.resize(48);
|
const unsigned int result_count = mysql_stmt_field_count(m_pkStmt);
|
||||||
memset(&m_vec_result[0], 0, sizeof(MYSQL_BIND) * 48);
|
if (result_count)
|
||||||
|
|
||||||
if (mysql_stmt_bind_result(m_pkStmt, &m_vec_result[0]))
|
|
||||||
{
|
{
|
||||||
Error("mysql_stmt_bind_result");
|
m_vec_result.resize(result_count);
|
||||||
return 0;
|
memset(&m_vec_result[0], 0, sizeof(MYSQL_BIND) * result_count);
|
||||||
|
m_vecResultLen.resize(result_count, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -87,16 +82,8 @@ bool CStmt::BindParam(enum_field_types type, void * p, int iMaxLen)
|
|||||||
bind->buffer_type = type;
|
bind->buffer_type = type;
|
||||||
bind->buffer = (void *) p;
|
bind->buffer = (void *) p;
|
||||||
bind->buffer_length = iMaxLen;
|
bind->buffer_length = iMaxLen;
|
||||||
bind->length = m_puiParamLen + m_uiParamCount;
|
bind->length = m_vecParamLen.empty() ? NULL : &m_vecParamLen[m_uiParamCount];
|
||||||
|
++m_uiParamCount;
|
||||||
if (++m_uiParamCount == m_vec_param.size())
|
|
||||||
{
|
|
||||||
if (mysql_stmt_bind_param(m_pkStmt, &m_vec_param[0]))
|
|
||||||
{
|
|
||||||
Error("mysql_stmt_bind_param");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -114,6 +101,7 @@ bool CStmt::BindResult(enum_field_types type, void * p, int iMaxLen)
|
|||||||
bind->buffer_type = type;
|
bind->buffer_type = type;
|
||||||
bind->buffer = (void *) p;
|
bind->buffer = (void *) p;
|
||||||
bind->buffer_length = iMaxLen;
|
bind->buffer_length = iMaxLen;
|
||||||
|
bind->length = m_vecResultLen.empty() ? NULL : &m_vecResultLen[m_uiResultCount - 1];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,9 +119,18 @@ int CStmt::Execute()
|
|||||||
|
|
||||||
if (bind->buffer_type == MYSQL_TYPE_STRING)
|
if (bind->buffer_type == MYSQL_TYPE_STRING)
|
||||||
{
|
{
|
||||||
*(m_puiParamLen + i) = strlen((const char *) bind->buffer);
|
m_vecParamLen[i] = strlen((const char *) bind->buffer);
|
||||||
sys_log(0, "param %d len %d buf %s", i, *m_puiParamLen, (const char *) bind->buffer);
|
|
||||||
}
|
}
|
||||||
|
else if (bind->buffer_type == MYSQL_TYPE_BLOB)
|
||||||
|
{
|
||||||
|
m_vecParamLen[i] = bind->buffer_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_vec_param.empty() && mysql_stmt_bind_param(m_pkStmt, &m_vec_param[0]))
|
||||||
|
{
|
||||||
|
Error("mysql_stmt_bind_param");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mysql_stmt_execute(m_pkStmt))
|
if (mysql_stmt_execute(m_pkStmt))
|
||||||
@@ -142,13 +139,31 @@ int CStmt::Execute()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mysql_stmt_store_result(m_pkStmt))
|
if (!m_vec_result.empty())
|
||||||
{
|
{
|
||||||
Error("mysql_store_result");
|
if (m_uiResultCount != m_vec_result.size())
|
||||||
return 0;
|
{
|
||||||
|
sys_log(0, "Result count mismatch %u, expected %zu query: %s", m_uiResultCount, m_vec_result.size(), m_stQuery.c_str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mysql_stmt_bind_result(m_pkStmt, &m_vec_result[0]))
|
||||||
|
{
|
||||||
|
Error("mysql_stmt_bind_result");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mysql_stmt_store_result(m_pkStmt))
|
||||||
|
{
|
||||||
|
Error("mysql_stmt_store_result");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
iRows = mysql_stmt_num_rows(m_pkStmt);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
iRows = mysql_stmt_num_rows(m_pkStmt);
|
iRows = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,4 +171,3 @@ bool CStmt::Fetch()
|
|||||||
{
|
{
|
||||||
return !mysql_stmt_fetch(m_pkStmt);
|
return !mysql_stmt_fetch(m_pkStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,10 +32,11 @@ class CStmt
|
|||||||
|
|
||||||
std::vector<MYSQL_BIND> m_vec_param;
|
std::vector<MYSQL_BIND> m_vec_param;
|
||||||
unsigned int m_uiParamCount;
|
unsigned int m_uiParamCount;
|
||||||
long unsigned int * m_puiParamLen;
|
std::vector<unsigned long> m_vecParamLen;
|
||||||
|
|
||||||
std::vector<MYSQL_BIND> m_vec_result;
|
std::vector<MYSQL_BIND> m_vec_result;
|
||||||
unsigned int m_uiResultCount;
|
unsigned int m_uiResultCount;
|
||||||
|
std::vector<unsigned long> m_vecResultLen;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user