fix for 45337 and some other little things

This commit is contained in:
David Anderson 2006-10-01 19:46:56 +00:00
parent f3057efd7d
commit fe1ebfe7bb
16 changed files with 141 additions and 47 deletions

View File

@ -55,6 +55,10 @@ static cell AMX_NATIVE_CALL SQL_MakeDbTuple(AMX *amx, cell *params)
sql->user = strdup(MF_GetAmxString(amx, params[2], 0, &len)); sql->user = strdup(MF_GetAmxString(amx, params[2], 0, &len));
sql->pass = strdup(MF_GetAmxString(amx, params[3], 0, &len)); sql->pass = strdup(MF_GetAmxString(amx, params[3], 0, &len));
sql->db = strdup(MF_GetAmxString(amx, params[4], 0, &len)); sql->db = strdup(MF_GetAmxString(amx, params[4], 0, &len));
if (params[0] / sizeof(cell) >= 5)
{
sql->max_timeout = static_cast<unsigned int>(params[5]);
}
unsigned int num = MakeHandle(sql, Handle_Connection, FreeConnection); unsigned int num = MakeHandle(sql, Handle_Connection, FreeConnection);
@ -87,11 +91,12 @@ static cell AMX_NATIVE_CALL SQL_Connect(AMX *amx, cell *params)
nfo.pass = sql->pass; nfo.pass = sql->pass;
nfo.port = sql->port; nfo.port = sql->port;
nfo.host = sql->host; nfo.host = sql->host;
nfo.max_timeout = sql->max_timeout;
char buffer[512]; char buffer[512];
int errcode; int errcode;
IDatabase *pDb = g_Mysql.Connect(&nfo, &errcode, buffer, sizeof(buffer)-1); IDatabase *pDb = g_Mysql.Connect2(&nfo, &errcode, buffer, sizeof(buffer)-1);
if (!pDb) if (!pDb)
{ {
@ -378,13 +383,15 @@ static cell AMX_NATIVE_CALL SQL_GetQueryString(AMX *amx, cell *params)
{ {
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query); AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo || !qInfo->pQuery) if (!qInfo || (!qInfo->pQuery && !qInfo->opt_ptr))
{ {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]); MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0; return 0;
} }
return MF_SetAmxString(amx, params[2], qInfo->pQuery->GetQueryString(), params[3]); const char *ptr = qInfo->pQuery ? qInfo->pQuery->GetQueryString() : qInfo->opt_ptr;
return MF_SetAmxString(amx, params[2], ptr, params[3]);
} }
static cell AMX_NATIVE_CALL SQL_FieldNameToNum(AMX *amx, cell *params) static cell AMX_NATIVE_CALL SQL_FieldNameToNum(AMX *amx, cell *params)

View File

@ -134,11 +134,13 @@ namespace SourceMod
struct DatabaseInfo struct DatabaseInfo
{ {
DatabaseInfo() : max_timeout(0) { };
const char *host; const char *host;
const char *database; const char *database;
const char *user; const char *user;
const char *pass; const char *pass;
unsigned int port; unsigned int port;
unsigned int max_timeout;
}; };
class ISQLDriver class ISQLDriver
@ -147,6 +149,8 @@ namespace SourceMod
virtual ~ISQLDriver() { }; virtual ~ISQLDriver() { };
public: public:
virtual IDatabase *Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength) =0; virtual IDatabase *Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength) =0;
//Supports the timeout clause
virtual IDatabase *Connect2(DatabaseInfo *info, int *errcode, char *error, size_t maxlength) =0;
virtual const char *NameString() =0; virtual const char *NameString() =0;
virtual bool IsCompatDriver(const char *namestring) =0; virtual bool IsCompatDriver(const char *namestring) =0;
}; };

View File

@ -21,6 +21,16 @@ const char *MysqlDriver::NameString()
} }
IDatabase *MysqlDriver::Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength) IDatabase *MysqlDriver::Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength)
{
return _Connect(info, errcode, error, maxlength, false);
}
IDatabase *MysqlDriver::Connect2(DatabaseInfo *info, int *errcode, char *error, size_t maxlength)
{
return _Connect(info, errcode, error, maxlength, true);
}
IDatabase *MysqlDriver::_Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength, bool do_timeout)
{ {
MYSQL *mysql = mysql_init(NULL); MYSQL *mysql = mysql_init(NULL);
@ -35,6 +45,11 @@ IDatabase *MysqlDriver::Connect(DatabaseInfo *info, int *errcode, char *error, s
return false; return false;
} }
if (do_timeout && info->max_timeout)
{
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&(info->max_timeout));
}
if (mysql_real_connect(mysql, if (mysql_real_connect(mysql,
info->host, info->host,
info->user, info->user,
@ -45,9 +60,13 @@ IDatabase *MysqlDriver::Connect(DatabaseInfo *info, int *errcode, char *error, s
0) == NULL) 0) == NULL)
{ {
if (errcode) if (errcode)
{
*errcode = mysql_errno(mysql); *errcode = mysql_errno(mysql);
}
if (error && maxlength) if (error && maxlength)
{
snprintf(error, maxlength, "%s", mysql_error(mysql)); snprintf(error, maxlength, "%s", mysql_error(mysql));
}
return false; return false;
} }

View File

@ -9,8 +9,11 @@ namespace SourceMod
{ {
public: public:
IDatabase *Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength); IDatabase *Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength);
IDatabase *Connect2(DatabaseInfo *info, int *errcode, char *error, size_t maxlength);
const char *NameString(); const char *NameString();
bool IsCompatDriver(const char *namestring); bool IsCompatDriver(const char *namestring);
public:
IDatabase *_Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength, bool do_timeout);
}; };
}; };

View File

@ -10,9 +10,11 @@
struct AmxQueryInfo struct AmxQueryInfo
{ {
AmxQueryInfo() : opt_ptr(NULL) { };
IQuery *pQuery; IQuery *pQuery;
QueryInfo info; QueryInfo info;
char error[255]; char error[255];
char *opt_ptr;
}; };
enum HandleType enum HandleType
@ -32,6 +34,7 @@ struct SQL_Connection
char *pass; char *pass;
char *db; char *db;
int port; int port;
unsigned int max_timeout;
}; };
typedef void (*FREEHANDLE)(void *, unsigned int); typedef void (*FREEHANDLE)(void *, unsigned int);

View File

@ -58,7 +58,7 @@ static cell AMX_NATIVE_CALL SQL_ThreadQuery(AMX *amx, cell *params)
int len; int len;
const char *handler = MF_GetAmxString(amx, params[2], 0, &len); const char *handler = MF_GetAmxString(amx, params[2], 0, &len);
int fwd = MF_RegisterSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_STRING, FP_CELL, FP_ARRAY, FP_CELL, FP_DONE); int fwd = MF_RegisterSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_STRING, FP_CELL, FP_ARRAY, FP_CELL, FP_CELL, FP_DONE);
if (fwd < 1) if (fwd < 1)
{ {
MF_LogError(amx, AMX_ERR_NATIVE, "Function not found: %s", handler); MF_LogError(amx, AMX_ERR_NATIVE, "Function not found: %s", handler);
@ -76,7 +76,7 @@ static cell AMX_NATIVE_CALL SQL_ThreadQuery(AMX *amx, cell *params)
} }
g_QueueLock->Unlock(); g_QueueLock->Unlock();
kmThread->SetInfo(cn->host, cn->user, cn->pass, cn->db, cn->port); kmThread->SetInfo(cn->host, cn->user, cn->pass, cn->db, cn->port, cn->max_timeout);
kmThread->SetForward(fwd); kmThread->SetForward(fwd);
kmThread->SetQuery(MF_GetAmxString(amx, params[3], 1, &len)); kmThread->SetQuery(MF_GetAmxString(amx, params[3], 1, &len));
kmThread->SetCellData(MF_GetAmxAddr(amx, params[4]), (ucell)params[5]); kmThread->SetCellData(MF_GetAmxAddr(amx, params[4]), (ucell)params[5]);
@ -126,13 +126,15 @@ void MysqlThread::SetForward(int forward)
m_fwd = forward; m_fwd = forward;
} }
void MysqlThread::SetInfo(const char *host, const char *user, const char *pass, const char *db, int port) void MysqlThread::SetInfo(const char *host, const char *user, const char *pass, const char *db, int port, unsigned int max_timeout)
{ {
m_host.assign(host); m_host.assign(host);
m_user.assign(user); m_user.assign(user);
m_pass.assign(pass); m_pass.assign(pass);
m_db.assign(db); m_db.assign(db);
m_max_timeout = m_max_timeout;
m_port = port; m_port = port;
m_qrInfo.queue_time = gpGlobals->time;
} }
void MysqlThread::SetQuery(const char *query) void MysqlThread::SetQuery(const char *query)
@ -149,10 +151,15 @@ void MysqlThread::RunThread(IThreadHandle *pHandle)
info.user = m_user.c_str(); info.user = m_user.c_str();
info.host = m_host.c_str(); info.host = m_host.c_str();
info.port = m_port; info.port = m_port;
info.max_timeout = m_max_timeout;
float save_time = m_qrInfo.queue_time;
memset(&m_qrInfo, 0, sizeof(m_qrInfo)); memset(&m_qrInfo, 0, sizeof(m_qrInfo));
IDatabase *pDatabase = g_Mysql.Connect(&info, &m_qrInfo.amxinfo.info.errorcode, m_qrInfo.amxinfo.error, 254); m_qrInfo.queue_time = save_time;
IDatabase *pDatabase = g_Mysql.Connect2(&info, &m_qrInfo.amxinfo.info.errorcode, m_qrInfo.amxinfo.error, 254);
IQuery *pQuery = NULL; IQuery *pQuery = NULL;
if (!pDatabase) if (!pDatabase)
{ {
@ -172,14 +179,15 @@ void MysqlThread::RunThread(IThreadHandle *pHandle)
if (m_qrInfo.query_success && m_qrInfo.amxinfo.info.rs) if (m_qrInfo.query_success && m_qrInfo.amxinfo.info.rs)
{ {
m_atomicResult.CopyFrom(m_qrInfo.amxinfo.info.rs); m_atomicResult.CopyFrom(m_qrInfo.amxinfo.info.rs);
m_qrInfo.amxinfo.pQuery = pQuery;
m_qrInfo.amxinfo.info.rs = &m_atomicResult; m_qrInfo.amxinfo.info.rs = &m_atomicResult;
}
if (pQuery)
{
m_qrInfo.amxinfo.pQuery = pQuery;
} else { } else {
if (pQuery) m_qrInfo.amxinfo.opt_ptr = new char[m_query.size() + 1];
{ strcpy(m_qrInfo.amxinfo.opt_ptr, m_query.c_str());
pQuery->FreeHandle();
}
pQuery = NULL;
} }
if (pDatabase) if (pDatabase)
@ -231,31 +239,37 @@ void MysqlThread::Execute()
} else if (!m_qrInfo.query_success) { } else if (!m_qrInfo.query_success) {
state = -1; state = -1;
} }
float diff = gpGlobals->time - m_qrInfo.queue_time;
cell c_diff = amx_ftoc(diff);
unsigned int hndl = MakeHandle(&m_qrInfo.amxinfo, Handle_Query, NullFunc);
if (state != 0) if (state != 0)
{ {
MF_ExecuteForward(m_fwd, MF_ExecuteForward(m_fwd,
(cell)state, (cell)state,
(cell)0, (cell)hndl,
m_qrInfo.amxinfo.error, m_qrInfo.amxinfo.error,
m_qrInfo.amxinfo.info.errorcode, m_qrInfo.amxinfo.info.errorcode,
data_addr, data_addr,
m_datalen); m_datalen,
c_diff);
} else { } else {
unsigned int hndl = MakeHandle(&m_qrInfo.amxinfo, Handle_Query, NullFunc);
MF_ExecuteForward(m_fwd, MF_ExecuteForward(m_fwd,
(cell)0, (cell)0,
(cell)hndl, (cell)hndl,
"", "",
(cell)0, (cell)0,
data_addr, data_addr,
m_datalen); m_datalen,
/* this should always be true I think */ c_diff);
if (m_qrInfo.amxinfo.pQuery)
{
m_qrInfo.amxinfo.pQuery->FreeHandle();
}
FreeHandle(hndl);
} }
FreeHandle(hndl);
if (m_qrInfo.amxinfo.pQuery)
{
m_qrInfo.amxinfo.pQuery->FreeHandle();
m_qrInfo.amxinfo.pQuery = NULL;
}
delete [] m_qrInfo.amxinfo.opt_ptr;
m_qrInfo.amxinfo.opt_ptr = NULL;
} }
/***************** /*****************

View File

@ -12,6 +12,7 @@ struct QueuedResultInfo
AmxQueryInfo amxinfo; AmxQueryInfo amxinfo;
bool connect_success; bool connect_success;
bool query_success; bool query_success;
float queue_time;
}; };
class AtomicResult : class AtomicResult :
@ -59,7 +60,7 @@ public:
MysqlThread(); MysqlThread();
~MysqlThread(); ~MysqlThread();
public: public:
void SetInfo(const char *host, const char *user, const char *pass, const char *db, int port); void SetInfo(const char *host, const char *user, const char *pass, const char *db, int port, unsigned int max_timeout);
void SetQuery(const char *query); void SetQuery(const char *query);
void SetCellData(cell data[], ucell len); void SetCellData(cell data[], ucell len);
void SetForward(int forward); void SetForward(int forward);
@ -74,6 +75,7 @@ private:
SourceHook::String m_user; SourceHook::String m_user;
SourceHook::String m_pass; SourceHook::String m_pass;
SourceHook::String m_db; SourceHook::String m_db;
unsigned int m_max_timeout;
int m_port; int m_port;
cell *m_data; cell *m_data;
ucell m_datalen; ucell m_datalen;

View File

@ -382,13 +382,16 @@ static cell AMX_NATIVE_CALL SQL_FieldNumToName(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL SQL_GetQueryString(AMX *amx, cell *params) static cell AMX_NATIVE_CALL SQL_GetQueryString(AMX *amx, cell *params)
{ {
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query); AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo)
if (!qInfo || (!qInfo->pQuery && !qInfo->opt_ptr))
{ {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]); MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0; return 0;
} }
return MF_SetAmxString(amx, params[2], qInfo->pQuery->GetQueryString(), params[3]); const char *ptr = qInfo->pQuery ? qInfo->pQuery->GetQueryString() : qInfo->opt_ptr;
return MF_SetAmxString(amx, params[2], ptr, params[3]);
} }
static cell AMX_NATIVE_CALL SQL_FieldNameToNum(AMX *amx, cell *params) static cell AMX_NATIVE_CALL SQL_FieldNameToNum(AMX *amx, cell *params)

View File

@ -23,6 +23,7 @@
namespace SourceHook namespace SourceHook
{ {
//This class is from CSDM for AMX Mod X //This class is from CSDM for AMX Mod X
/* /*
A circular, doubly-linked list with one sentinel node A circular, doubly-linked list with one sentinel node

View File

@ -10,9 +10,11 @@
struct AmxQueryInfo struct AmxQueryInfo
{ {
AmxQueryInfo() : opt_ptr(NULL) { };
IQuery *pQuery; IQuery *pQuery;
QueryInfo info; QueryInfo info;
char error[255]; char error[255];
char *opt_ptr;
}; };
enum HandleType enum HandleType

View File

@ -54,6 +54,9 @@ void ThreadWorker::RunThread(IThreadHandle *pHandle)
/** /**
* Check number of items in the queue * Check number of items in the queue
*/ */
m_StateLock->Lock();
this_state = m_state;
m_StateLock->Unlock();
if (this_state != Worker_Stopped) if (this_state != Worker_Stopped)
{ {
m_QueueLock->Lock(); m_QueueLock->Lock();
@ -65,6 +68,11 @@ void ThreadWorker::RunThread(IThreadHandle *pHandle)
*/ */
m_Waiting = true; m_Waiting = true;
m_QueueLock->Unlock(); m_QueueLock->Unlock();
/* first check if we should end again */
if (this_state == Worker_Stopped)
{
break;
}
m_AddSignal->Wait(); m_AddSignal->Wait();
m_Waiting = false; m_Waiting = false;
} else { } else {
@ -80,7 +88,9 @@ void ThreadWorker::RunThread(IThreadHandle *pHandle)
{ {
//wait until the lock is cleared. //wait until the lock is cleared.
if (this_state == Worker_Paused) if (this_state == Worker_Paused)
{
m_PauseSignal->Wait(); m_PauseSignal->Wait();
}
if (this_state == Worker_Stopped) if (this_state == Worker_Stopped)
{ {
//if we're supposed to flush cleanrly, //if we're supposed to flush cleanrly,
@ -187,9 +197,12 @@ bool ThreadWorker::Stop(bool flush_cancel)
{ {
Unpause(); Unpause();
} else { } else {
m_AddSignal->Signal(); m_QueueLock->Lock();
Pause(); if (m_Waiting)
Unpause(); {
m_AddSignal->Signal();
}
m_QueueLock->Unlock();
} }
me->WaitForThread(); me->WaitForThread();

View File

@ -97,7 +97,7 @@ IThreadHandle *WinThreader::MakeThread(IThread *pThread, const ThreadParams *par
IEventSignal *WinThreader::MakeEventSignal() IEventSignal *WinThreader::MakeEventSignal()
{ {
HANDLE event = CreateEventA(NULL, TRUE, TRUE, NULL); HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL);
if (!event) if (!event)
return NULL; return NULL;
@ -275,7 +275,6 @@ WinThreader::WinEvent::~WinEvent()
void WinThreader::WinEvent::Wait() void WinThreader::WinEvent::Wait()
{ {
WaitForSingleObject(m_event, INFINITE); WaitForSingleObject(m_event, INFINITE);
ResetEvent(m_event);
} }
void WinThreader::WinEvent::Signal() void WinThreader::WinEvent::Signal()

View File

@ -129,6 +129,7 @@ void MysqlThread::SetForward(int forward)
void MysqlThread::SetInfo(const char *db) void MysqlThread::SetInfo(const char *db)
{ {
m_db.assign(db); m_db.assign(db);
m_qrInfo.queue_time = gpGlobals->time;
} }
void MysqlThread::SetQuery(const char *query) void MysqlThread::SetQuery(const char *query)
@ -146,8 +147,12 @@ void MysqlThread::RunThread(IThreadHandle *pHandle)
info.host = ""; info.host = "";
info.port = 0; info.port = 0;
float save_time = m_qrInfo.queue_time;
memset(&m_qrInfo, 0, sizeof(m_qrInfo)); memset(&m_qrInfo, 0, sizeof(m_qrInfo));
m_qrInfo.queue_time = save_time;
IDatabase *pDatabase = g_Sqlite.Connect(&info, &m_qrInfo.amxinfo.info.errorcode, m_qrInfo.amxinfo.error, 254); IDatabase *pDatabase = g_Sqlite.Connect(&info, &m_qrInfo.amxinfo.info.errorcode, m_qrInfo.amxinfo.error, 254);
IQuery *pQuery = NULL; IQuery *pQuery = NULL;
if (!pDatabase) if (!pDatabase)
@ -168,15 +173,17 @@ void MysqlThread::RunThread(IThreadHandle *pHandle)
if (m_qrInfo.query_success && m_qrInfo.amxinfo.info.rs) if (m_qrInfo.query_success && m_qrInfo.amxinfo.info.rs)
{ {
m_atomicResult.CopyFrom(m_qrInfo.amxinfo.info.rs); m_atomicResult.CopyFrom(m_qrInfo.amxinfo.info.rs);
m_qrInfo.amxinfo.pQuery = NULL;
m_qrInfo.amxinfo.info.rs = &m_atomicResult; m_qrInfo.amxinfo.info.rs = &m_atomicResult;
} }
if (pQuery) if (pQuery)
{ {
pQuery->FreeHandle(); m_qrInfo.amxinfo.pQuery = pQuery;
pQuery = NULL; } else {
m_qrInfo.amxinfo.opt_ptr = new char[m_query.size() + 1];
strcpy(m_qrInfo.amxinfo.opt_ptr, m_query.c_str());
} }
if (pDatabase) if (pDatabase)
{ {
pDatabase->FreeHandle(); pDatabase->FreeHandle();
@ -226,26 +233,37 @@ void MysqlThread::Execute()
} else if (!m_qrInfo.query_success) { } else if (!m_qrInfo.query_success) {
state = -1; state = -1;
} }
float diff = gpGlobals->time - m_qrInfo.queue_time;
cell c_diff = amx_ftoc(diff);
unsigned int hndl = MakeHandle(&m_qrInfo.amxinfo, Handle_Query, NullFunc);
if (state != 0) if (state != 0)
{ {
MF_ExecuteForward(m_fwd, MF_ExecuteForward(m_fwd,
(cell)state, (cell)state,
(cell)0, (cell)hndl,
m_qrInfo.amxinfo.error, m_qrInfo.amxinfo.error,
m_qrInfo.amxinfo.info.errorcode, m_qrInfo.amxinfo.info.errorcode,
data_addr, data_addr,
m_datalen); m_datalen,
c_diff);
} else { } else {
unsigned int hndl = MakeHandle(&m_qrInfo.amxinfo, Handle_Query, NullFunc);
MF_ExecuteForward(m_fwd, MF_ExecuteForward(m_fwd,
(cell)0, (cell)0,
(cell)hndl, (cell)hndl,
"", "",
(cell)0, (cell)0,
data_addr, data_addr,
m_datalen); m_datalen,
FreeHandle(hndl); c_diff);
} }
FreeHandle(hndl);
if (m_qrInfo.amxinfo.pQuery)
{
m_qrInfo.amxinfo.pQuery->FreeHandle();
m_qrInfo.amxinfo.pQuery = NULL;
}
delete [] m_qrInfo.amxinfo.opt_ptr;
m_qrInfo.amxinfo.opt_ptr = NULL;
} }
/***************** /*****************

View File

@ -12,6 +12,7 @@ struct QueuedResultInfo
AmxQueryInfo amxinfo; AmxQueryInfo amxinfo;
bool connect_success; bool connect_success;
bool query_success; bool query_success;
float queue_time;
}; };
class AtomicResult : class AtomicResult :

View File

@ -30,8 +30,12 @@ enum Handle
* !!NOTE!! I have seen most people think that this connects to the DB. * !!NOTE!! I have seen most people think that this connects to the DB.
* Nowhere does it say this, and in fact it does not. It only caches * Nowhere does it say this, and in fact it does not. It only caches
* the connection information, the host/user/pass/etc. * the connection information, the host/user/pass/etc.
*
* The optional timeout parameter specifies how long connections should wait before
* giving up. If 0, the default (which is undefined) is used.
*
*/ */
native Handle:SQL_MakeDbTuple(const host[], const user[], const pass[], const db[]); native Handle:SQL_MakeDbTuple(const host[], const user[], const pass[], const db[], timeout=0);
/** /**
@ -74,8 +78,9 @@ native Handle:SQL_PrepareQuery(Handle:db, const fmt[], {Float,_}:...);
* @param errnum - An error code, if any. * @param errnum - An error code, if any.
* @param data - Data array you passed in. * @param data - Data array you passed in.
* @param size - Size of the data array you passed in. * @param size - Size of the data array you passed in.
* @param queuetime - Amount of gametime that passed while the query was resolving.
* *
* public QueryHandler(failstate, Handle:query, error[], errnum, data[], size) * public QueryHandler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime)
* *
* Note! The handle you pass in is a DB Tuple, NOT an active connection! * Note! The handle you pass in is a DB Tuple, NOT an active connection!
* Note! The handle does not need to be freed. * Note! The handle does not need to be freed.

View File

@ -106,22 +106,22 @@ PrintQueryData(Handle:query)
/** /**
* Handler for when a threaded query is resolved. * Handler for when a threaded query is resolved.
*/ */
public GetMyStuff(failstate, Handle:query, error[], errnum, data[], size) public GetMyStuff(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime)
{ {
server_print("Resolved query %d at: %f", data[0], get_gametime()) server_print(" --> Resolved query %d, took %f seconds", data[0], queuetime)
if (failstate) if (failstate)
{ {
if (failstate == TQUERY_CONNECT_FAILED) if (failstate == TQUERY_CONNECT_FAILED)
{ {
server_print("Connection failed!") server_print(" --> Connection failed!")
} else if (failstate == TQUERY_QUERY_FAILED) { } else if (failstate == TQUERY_QUERY_FAILED) {
server_print("Query failed!") server_print(" --> Query failed!")
} }
server_print("Error code: %d (Message: ^"%s^")", errnum, error) server_print(" --> Error code: %d (Message: ^"%s^")", errnum, error)
new querystring[1024] new querystring[1024]
SQL_GetQueryString(query, querystring, 1023) SQL_GetQueryString(query, querystring, 1023)
server_print("Original query: %s", querystring) server_print(" --> Original query: %s", querystring)
} else { } else {
PrintQueryData(query) PrintQueryData(query)
} }