mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-24 13:55:36 +03:00
added amb281 - multiple result sets for MySQL
This commit is contained in:
parent
2d737970d0
commit
a86b1c5097
@ -489,6 +489,34 @@ static cell AMX_NATIVE_CALL SQL_Rewind(AMX *amx, cell *params)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL SQL_NextResultSet(AMX *amx, cell *params)
|
||||||
|
{
|
||||||
|
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
|
||||||
|
if (!qInfo)
|
||||||
|
{
|
||||||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
IResultSet *rs = qInfo->info.rs;
|
||||||
|
|
||||||
|
if (!rs)
|
||||||
|
{
|
||||||
|
MF_LogError(amx, AMX_ERR_NATIVE, "No result set in this query!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rs->NextResultSet())
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qInfo->info.rs = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL SQL_QuoteString(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL SQL_QuoteString(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
IDatabase *pDb = (IDatabase *)GetHandle(params[1], Handle_Database);
|
IDatabase *pDb = (IDatabase *)GetHandle(params[1], Handle_Database);
|
||||||
@ -559,6 +587,7 @@ AMX_NATIVE_INFO g_BaseSqlNatives[] =
|
|||||||
{"SQL_Rewind", SQL_Rewind},
|
{"SQL_Rewind", SQL_Rewind},
|
||||||
{"SQL_QuoteString", SQL_QuoteString},
|
{"SQL_QuoteString", SQL_QuoteString},
|
||||||
{"SQL_QuoteStringFmt", SQL_QuoteStringFmt},
|
{"SQL_QuoteStringFmt", SQL_QuoteStringFmt},
|
||||||
|
{"SQL_NextResultSet", SQL_NextResultSet},
|
||||||
|
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
@ -61,6 +61,10 @@ namespace SourceMod
|
|||||||
* Rewinds to the first row.
|
* Rewinds to the first row.
|
||||||
*/
|
*/
|
||||||
virtual void Rewind() =0;
|
virtual void Rewind() =0;
|
||||||
|
/**
|
||||||
|
* Transitions to the next result set, if any is available.
|
||||||
|
*/
|
||||||
|
virtual bool NextResultSet() =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QueryInfo
|
struct QueryInfo
|
||||||
|
@ -57,7 +57,7 @@ IDatabase *MysqlDriver::_Connect(DatabaseInfo *info, int *errcode, char *error,
|
|||||||
info->database,
|
info->database,
|
||||||
info->port,
|
info->port,
|
||||||
NULL,
|
NULL,
|
||||||
0) == NULL)
|
CLIENT_MULTI_STATEMENTS) == NULL)
|
||||||
{
|
{
|
||||||
if (errcode)
|
if (errcode)
|
||||||
{
|
{
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#if defined WIN32 || defined _WIN32
|
#if defined WIN32 || defined _WIN32
|
||||||
#include <winsock.h>
|
#include <winsock.h>
|
||||||
#endif
|
#endif
|
||||||
|
typedef unsigned long ulong;
|
||||||
#include <mysql.h>
|
#include <mysql.h>
|
||||||
|
|
||||||
#endif //_INCLUDE_SOURCEMOD_MYSQL_HEADERS_H
|
#endif //_INCLUDE_SOURCEMOD_MYSQL_HEADERS_H
|
||||||
|
@ -84,7 +84,9 @@ bool MysqlQuery::ExecuteR(QueryInfo *info, char *error, size_t maxlength)
|
|||||||
{
|
{
|
||||||
snprintf(error, maxlength, "%s", mysql_error(m_pDatabase->m_pMysql));
|
snprintf(error, maxlength, "%s", mysql_error(m_pDatabase->m_pMysql));
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
MYSQL_RES *res = mysql_store_result(m_pDatabase->m_pMysql);
|
MYSQL_RES *res = mysql_store_result(m_pDatabase->m_pMysql);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
@ -105,7 +107,7 @@ bool MysqlQuery::ExecuteR(QueryInfo *info, char *error, size_t maxlength)
|
|||||||
info->errorcode = 0;
|
info->errorcode = 0;
|
||||||
info->success = true;
|
info->success = true;
|
||||||
info->affected_rows = mysql_affected_rows(m_pDatabase->m_pMysql);
|
info->affected_rows = mysql_affected_rows(m_pDatabase->m_pMysql);
|
||||||
MysqlResultSet *rs = new MysqlResultSet(res);
|
MysqlResultSet *rs = new MysqlResultSet(res, m_pDatabase->m_pMysql);
|
||||||
info->rs = rs;
|
info->rs = rs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,11 +61,12 @@ int MysqlResultRow::GetInt(unsigned int columnId)
|
|||||||
return atoi(GetStringSafe(columnId));
|
return atoi(GetStringSafe(columnId));
|
||||||
}
|
}
|
||||||
|
|
||||||
MysqlResultSet::MysqlResultSet(MYSQL_RES *res) :
|
MysqlResultSet::MysqlResultSet(MYSQL_RES *res, MYSQL *mysql) :
|
||||||
m_pRes(res)
|
m_pRes(res)
|
||||||
{
|
{
|
||||||
m_Rows = (unsigned int)mysql_num_rows(res);
|
m_Rows = (unsigned int)mysql_num_rows(res);
|
||||||
m_Columns = (unsigned int)mysql_num_fields(res);
|
m_Columns = (unsigned int)mysql_num_fields(res);
|
||||||
|
m_pMySQL = mysql;
|
||||||
|
|
||||||
if (m_Rows > 0)
|
if (m_Rows > 0)
|
||||||
{
|
{
|
||||||
@ -77,7 +78,49 @@ MysqlResultSet::MysqlResultSet(MYSQL_RES *res) :
|
|||||||
|
|
||||||
MysqlResultSet::~MysqlResultSet()
|
MysqlResultSet::~MysqlResultSet()
|
||||||
{
|
{
|
||||||
|
if (m_pRes == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mysql_free_result(m_pRes);
|
mysql_free_result(m_pRes);
|
||||||
|
while (mysql_next_result(m_pMySQL) == 0)
|
||||||
|
{
|
||||||
|
m_pRes = mysql_store_result(m_pMySQL);
|
||||||
|
if (m_pRes != NULL)
|
||||||
|
{
|
||||||
|
mysql_free_result(m_pRes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MysqlResultSet::NextResultSet()
|
||||||
|
{
|
||||||
|
if (!mysql_more_results(m_pMySQL))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_free_result(m_pRes);
|
||||||
|
if (mysql_next_result(m_pMySQL) != 0
|
||||||
|
|| (m_pRes = mysql_store_result(m_pMySQL)) == NULL)
|
||||||
|
{
|
||||||
|
m_Rows = 0;
|
||||||
|
m_pRes = NULL;
|
||||||
|
m_Columns = 0;
|
||||||
|
m_kRow.m_CurRow = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Rows = (unsigned int)mysql_num_rows(m_pRes);
|
||||||
|
m_Columns = (unsigned int)mysql_num_fields(m_pRes);
|
||||||
|
|
||||||
|
if (m_Rows > 0)
|
||||||
|
{
|
||||||
|
NextRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_kRow.m_Columns = m_Columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MysqlResultSet::FreeHandle()
|
void MysqlResultSet::FreeHandle()
|
||||||
|
@ -30,7 +30,7 @@ namespace SourceMod
|
|||||||
class MysqlResultSet : public IResultSet
|
class MysqlResultSet : public IResultSet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MysqlResultSet(MYSQL_RES *res);
|
MysqlResultSet(MYSQL_RES *res, MYSQL *mysql);
|
||||||
~MysqlResultSet();
|
~MysqlResultSet();
|
||||||
public:
|
public:
|
||||||
void FreeHandle();
|
void FreeHandle();
|
||||||
@ -44,7 +44,9 @@ namespace SourceMod
|
|||||||
IResultRow *GetRow();
|
IResultRow *GetRow();
|
||||||
void NextRow();
|
void NextRow();
|
||||||
void Rewind();
|
void Rewind();
|
||||||
|
bool NextResultSet();
|
||||||
private:
|
private:
|
||||||
|
MYSQL *m_pMySQL;
|
||||||
MYSQL_RES *m_pRes;
|
MYSQL_RES *m_pRes;
|
||||||
MysqlResultRow m_kRow;
|
MysqlResultRow m_kRow;
|
||||||
unsigned int m_Columns;
|
unsigned int m_Columns;
|
||||||
|
@ -566,6 +566,11 @@ void AtomicResult::Rewind()
|
|||||||
m_CurRow = 1;
|
m_CurRow = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AtomicResult::NextResultSet()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
AMX_NATIVE_INFO g_ThreadSqlNatives[] =
|
AMX_NATIVE_INFO g_ThreadSqlNatives[] =
|
||||||
{
|
{
|
||||||
{"SQL_ThreadQuery", SQL_ThreadQuery},
|
{"SQL_ThreadQuery", SQL_ThreadQuery},
|
||||||
|
@ -34,6 +34,7 @@ public:
|
|||||||
virtual IResultRow *GetRow();
|
virtual IResultRow *GetRow();
|
||||||
virtual void NextRow();
|
virtual void NextRow();
|
||||||
virtual void Rewind();
|
virtual void Rewind();
|
||||||
|
virtual bool NextResultSet();
|
||||||
public:
|
public:
|
||||||
virtual const char *GetString(unsigned int columnId);
|
virtual const char *GetString(unsigned int columnId);
|
||||||
virtual const char *GetStringSafe(unsigned int columnId);
|
virtual const char *GetStringSafe(unsigned int columnId);
|
||||||
|
@ -489,6 +489,34 @@ static cell AMX_NATIVE_CALL SQL_Rewind(AMX *amx, cell *params)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL SQL_NextResultSet(AMX *amx, cell *params)
|
||||||
|
{
|
||||||
|
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
|
||||||
|
if (!qInfo)
|
||||||
|
{
|
||||||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
IResultSet *rs = qInfo->info.rs;
|
||||||
|
|
||||||
|
if (!rs)
|
||||||
|
{
|
||||||
|
MF_LogError(amx, AMX_ERR_NATIVE, "No result set in this query!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rs->NextResultSet())
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qInfo->info.rs = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL SQL_QuoteString(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL SQL_QuoteString(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
IDatabase *pDb = (IDatabase *)GetHandle(params[1], Handle_Database);
|
IDatabase *pDb = (IDatabase *)GetHandle(params[1], Handle_Database);
|
||||||
@ -559,6 +587,7 @@ AMX_NATIVE_INFO g_BaseSqlNatives[] =
|
|||||||
{"SQL_Rewind", SQL_Rewind},
|
{"SQL_Rewind", SQL_Rewind},
|
||||||
{"SQL_QuoteString", SQL_QuoteString},
|
{"SQL_QuoteString", SQL_QuoteString},
|
||||||
{"SQL_QuoteStringFmt", SQL_QuoteStringFmt},
|
{"SQL_QuoteStringFmt", SQL_QuoteStringFmt},
|
||||||
|
{"SQL_NextResultSet", SQL_NextResultSet},
|
||||||
|
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
@ -61,6 +61,9 @@ namespace SourceMod
|
|||||||
* Resets back to the first row.
|
* Resets back to the first row.
|
||||||
*/
|
*/
|
||||||
virtual void Rewind() =0;
|
virtual void Rewind() =0;
|
||||||
|
|
||||||
|
/* Always returns false in Sqlite */
|
||||||
|
virtual bool NextResultSet() =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QueryInfo
|
struct QueryInfo
|
||||||
|
@ -164,3 +164,8 @@ void SqliteResultSet::Rewind()
|
|||||||
m_CurRow = 1;
|
m_CurRow = 1;
|
||||||
m_CurIndex = (m_CurRow * m_Columns);
|
m_CurIndex = (m_CurRow * m_Columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SqliteResultSet::NextResultSet()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@ -39,6 +39,7 @@ namespace SourceMod
|
|||||||
int GetInt(unsigned int columnId);
|
int GetInt(unsigned int columnId);
|
||||||
bool IsNull(unsigned int columnId);
|
bool IsNull(unsigned int columnId);
|
||||||
const char *GetRaw(unsigned int columnId, size_t *length);
|
const char *GetRaw(unsigned int columnId, size_t *length);
|
||||||
|
bool NextResultSet();
|
||||||
private:
|
private:
|
||||||
const char *GetStringSafe(unsigned int columnId);
|
const char *GetStringSafe(unsigned int columnId);
|
||||||
private:
|
private:
|
||||||
|
@ -560,6 +560,11 @@ void AtomicResult::Rewind()
|
|||||||
m_CurRow = 1;
|
m_CurRow = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AtomicResult::NextResultSet()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
AMX_NATIVE_INFO g_ThreadSqlNatives[] =
|
AMX_NATIVE_INFO g_ThreadSqlNatives[] =
|
||||||
{
|
{
|
||||||
{"SQL_ThreadQuery", SQL_ThreadQuery},
|
{"SQL_ThreadQuery", SQL_ThreadQuery},
|
||||||
|
@ -42,6 +42,7 @@ public:
|
|||||||
virtual int GetInt(unsigned int columnId);
|
virtual int GetInt(unsigned int columnId);
|
||||||
virtual bool IsNull(unsigned int columnId);
|
virtual bool IsNull(unsigned int columnId);
|
||||||
virtual const char *GetRaw(unsigned int columnId, size_t *length);
|
virtual const char *GetRaw(unsigned int columnId, size_t *length);
|
||||||
|
virtual bool NextResultSet();
|
||||||
public:
|
public:
|
||||||
void CopyFrom(IResultSet *rs);
|
void CopyFrom(IResultSet *rs);
|
||||||
private:
|
private:
|
||||||
|
@ -247,6 +247,20 @@ native SQL_SetAffinity(const driver[]);
|
|||||||
*/
|
*/
|
||||||
native SQL_GetQueryString(Handle:query, buffer[], maxlength);
|
native SQL_GetQueryString(Handle:query, buffer[], maxlength);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For queries which return multiple result sets, this advances to the next
|
||||||
|
* result set if one is available. Otherwise, the current result set is
|
||||||
|
* destroyed and will no longer be accessible.
|
||||||
|
*
|
||||||
|
* This function will always return false on SQLite, and when using threaded
|
||||||
|
* queries in MySQL. Nonetheless, it has the same effect of removing the last
|
||||||
|
* result set.
|
||||||
|
*
|
||||||
|
* @param query Query Handle.
|
||||||
|
* @return True on success, false on failure.
|
||||||
|
*/
|
||||||
|
native bool:SQL_NextResultSet(Handle:query);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function can be used to find out if a table in a Sqlite database exists.
|
* This function can be used to find out if a table in a Sqlite database exists.
|
||||||
* (updated for newer API)
|
* (updated for newer API)
|
||||||
|
Loading…
Reference in New Issue
Block a user