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->pass = strdup(MF_GetAmxString(amx, params[3], 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);
@ -87,11 +91,12 @@ static cell AMX_NATIVE_CALL SQL_Connect(AMX *amx, cell *params)
nfo.pass = sql->pass;
nfo.port = sql->port;
nfo.host = sql->host;
nfo.max_timeout = sql->max_timeout;
char buffer[512];
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)
{
@ -378,13 +383,15 @@ static cell AMX_NATIVE_CALL SQL_GetQueryString(AMX *amx, cell *params)
{
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]);
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)

View File

@ -134,11 +134,13 @@ namespace SourceMod
struct DatabaseInfo
{
DatabaseInfo() : max_timeout(0) { };
const char *host;
const char *database;
const char *user;
const char *pass;
unsigned int port;
unsigned int max_timeout;
};
class ISQLDriver
@ -147,6 +149,8 @@ namespace SourceMod
virtual ~ISQLDriver() { };
public:
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 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)
{
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);
@ -35,6 +45,11 @@ IDatabase *MysqlDriver::Connect(DatabaseInfo *info, int *errcode, char *error, s
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,
info->host,
info->user,
@ -45,9 +60,13 @@ IDatabase *MysqlDriver::Connect(DatabaseInfo *info, int *errcode, char *error, s
0) == NULL)
{
if (errcode)
{
*errcode = mysql_errno(mysql);
}
if (error && maxlength)
{
snprintf(error, maxlength, "%s", mysql_error(mysql));
}
return false;
}

View File

@ -9,8 +9,11 @@ namespace SourceMod
{
public:
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();
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
{
AmxQueryInfo() : opt_ptr(NULL) { };
IQuery *pQuery;
QueryInfo info;
char error[255];
char *opt_ptr;
};
enum HandleType
@ -32,6 +34,7 @@ struct SQL_Connection
char *pass;
char *db;
int port;
unsigned int max_timeout;
};
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;
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)
{
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();
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->SetQuery(MF_GetAmxString(amx, params[3], 1, &len));
kmThread->SetCellData(MF_GetAmxAddr(amx, params[4]), (ucell)params[5]);
@ -126,13 +126,15 @@ void MysqlThread::SetForward(int 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_user.assign(user);
m_pass.assign(pass);
m_db.assign(db);
m_max_timeout = m_max_timeout;
m_port = port;
m_qrInfo.queue_time = gpGlobals->time;
}
void MysqlThread::SetQuery(const char *query)
@ -149,10 +151,15 @@ void MysqlThread::RunThread(IThreadHandle *pHandle)
info.user = m_user.c_str();
info.host = m_host.c_str();
info.port = m_port;
info.max_timeout = m_max_timeout;
float save_time = m_qrInfo.queue_time;
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;
if (!pDatabase)
{
@ -172,14 +179,15 @@ void MysqlThread::RunThread(IThreadHandle *pHandle)
if (m_qrInfo.query_success && 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;
}
if (pQuery)
{
m_qrInfo.amxinfo.pQuery = pQuery;
} else {
if (pQuery)
{
pQuery->FreeHandle();
}
pQuery = NULL;
m_qrInfo.amxinfo.opt_ptr = new char[m_query.size() + 1];
strcpy(m_qrInfo.amxinfo.opt_ptr, m_query.c_str());
}
if (pDatabase)
@ -231,31 +239,37 @@ void MysqlThread::Execute()
} else if (!m_qrInfo.query_success) {
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)
{
MF_ExecuteForward(m_fwd,
(cell)state,
(cell)0,
(cell)hndl,
m_qrInfo.amxinfo.error,
m_qrInfo.amxinfo.info.errorcode,
data_addr,
m_datalen);
m_datalen,
c_diff);
} else {
unsigned int hndl = MakeHandle(&m_qrInfo.amxinfo, Handle_Query, NullFunc);
MF_ExecuteForward(m_fwd,
(cell)0,
(cell)hndl,
"",
(cell)0,
data_addr,
m_datalen);
/* this should always be true I think */
if (m_qrInfo.amxinfo.pQuery)
{
m_qrInfo.amxinfo.pQuery->FreeHandle();
}
FreeHandle(hndl);
m_datalen,
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;
bool connect_success;
bool query_success;
float queue_time;
};
class AtomicResult :
@ -59,7 +60,7 @@ public:
MysqlThread();
~MysqlThread();
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 SetCellData(cell data[], ucell len);
void SetForward(int forward);
@ -74,6 +75,7 @@ private:
SourceHook::String m_user;
SourceHook::String m_pass;
SourceHook::String m_db;
unsigned int m_max_timeout;
int m_port;
cell *m_data;
ucell m_datalen;