1.1 --- a/core/smn_database.cpp Sun May 22 02:04:34 2011 -0700
1.2 +++ b/core/smn_database.cpp Sat May 14 20:21:37 2011 -0700
1.3 @@ -36,9 +36,15 @@
1.4 #include "PluginSys.h"
1.5 #include "sm_stringutil.h"
1.6
1.7 -HandleType_t hQueryType;
1.8 HandleType_t hStmtType;
1.9
1.10 +HandleType_t hCombinedQueryType;
1.11 +typedef struct
1.12 +{
1.13 + IQuery *query;
1.14 + IDatabase *db;
1.15 +} CombinedQuery;
1.16 +
1.17 class DatabaseHelpers :
1.18 public SMGlobalClass,
1.19 public IHandleTypeDispatch
1.20 @@ -57,22 +63,23 @@
1.21 g_HandleSys.InitAccessDefaults(&tacc, NULL);
1.22 tacc.ident = g_pCoreIdent;
1.23
1.24 - hQueryType = g_HandleSys.CreateType("IQuery", this, 0, &tacc, &acc, g_pCoreIdent, NULL);
1.25 - hStmtType = g_HandleSys.CreateType("IPreparedQuery", this, hQueryType, &tacc, &acc, g_pCoreIdent, NULL);
1.26 + hCombinedQueryType = g_HandleSys.CreateType("IQuery", this, 0, &tacc, &acc, g_pCoreIdent, NULL);
1.27 + hStmtType = g_HandleSys.CreateType("IPreparedQuery", this, 0, &tacc, &acc, g_pCoreIdent, NULL);
1.28 }
1.29
1.30 virtual void OnSourceModShutdown()
1.31 {
1.32 g_HandleSys.RemoveType(hStmtType, g_pCoreIdent);
1.33 - g_HandleSys.RemoveType(hQueryType, g_pCoreIdent);
1.34 + g_HandleSys.RemoveType(hCombinedQueryType, g_pCoreIdent);
1.35 }
1.36
1.37 virtual void OnHandleDestroy(HandleType_t type, void *object)
1.38 {
1.39 - if (type == hQueryType)
1.40 + if (type == hCombinedQueryType)
1.41 {
1.42 - IQuery *query = (IQuery *)object;
1.43 - query->Destroy();
1.44 + CombinedQuery *combined = (CombinedQuery *)object;
1.45 + combined->query->Destroy();
1.46 + delete combined;
1.47 } else if (type == hStmtType) {
1.48 IPreparedQuery *query = (IPreparedQuery *)object;
1.49 query->Destroy();
1.50 @@ -84,10 +91,37 @@
1.51 inline HandleError ReadQueryHndl(Handle_t hndl, IPluginContext *pContext, IQuery **query)
1.52 {
1.53 HandleSecurity sec;
1.54 + CombinedQuery *c;
1.55 sec.pOwner = pContext->GetIdentity();
1.56 sec.pIdentity = g_pCoreIdent;
1.57
1.58 - return g_HandleSys.ReadHandle(hndl, hQueryType, &sec, (void **)query);
1.59 + HandleError ret;
1.60 +
1.61 + if ((ret = g_HandleSys.ReadHandle(hndl, hStmtType, &sec, (void **)query)) != HandleError_None)
1.62 + {
1.63 + ret = g_HandleSys.ReadHandle(hndl, hCombinedQueryType, &sec, (void **)&c);
1.64 + if (ret == HandleError_None)
1.65 + {
1.66 + *query = c->query;
1.67 + }
1.68 + }
1.69 + return ret;
1.70 +}
1.71 +
1.72 +inline HandleError ReadQueryAndDbHndl(Handle_t hndl, IPluginContext *pContext, IQuery **query, IDatabase **db)
1.73 +{
1.74 + HandleSecurity sec;
1.75 + CombinedQuery *c;
1.76 + sec.pOwner = pContext->GetIdentity();
1.77 + sec.pIdentity = g_pCoreIdent;
1.78 +
1.79 + HandleError ret = g_HandleSys.ReadHandle(hndl, hCombinedQueryType, &sec, (void **)&c);
1.80 + if (ret == HandleError_None)
1.81 + {
1.82 + *query = c->query;
1.83 + *db = c->db;
1.84 + }
1.85 + return ret;
1.86 }
1.87
1.88 inline HandleError ReadStmtHndl(Handle_t hndl, IPluginContext *pContext, IPreparedQuery **query)
1.89 @@ -192,12 +226,17 @@
1.90
1.91 if (m_pQuery)
1.92 {
1.93 - qh = g_HandleSys.CreateHandle(hQueryType, m_pQuery, me->GetIdentity(), g_pCoreIdent, NULL);
1.94 + CombinedQuery *c = new CombinedQuery;
1.95 + c->query = m_pQuery;
1.96 + c->db = m_pDatabase;
1.97 +
1.98 + qh = g_HandleSys.CreateHandle(hCombinedQueryType, c, me->GetIdentity(), g_pCoreIdent, NULL);
1.99 if (qh != BAD_HANDLE)
1.100 {
1.101 m_pQuery = NULL;
1.102 } else {
1.103 UTIL_Format(error, sizeof(error), "Could not alloc handle");
1.104 + delete c;
1.105 }
1.106 }
1.107
1.108 @@ -537,42 +576,59 @@
1.109 {
1.110 IDatabase *db = NULL;
1.111 IPreparedQuery *stmt = NULL;
1.112 + IQuery *query = NULL;
1.113 HandleError err;
1.114
1.115 - if ((err = ReadDbOrStmtHndl(params[1], pContext, &db, &stmt)) != HandleError_None)
1.116 + if (((err = ReadDbOrStmtHndl(params[1], pContext, &db, &stmt)) != HandleError_None)
1.117 + && ((err = ReadQueryAndDbHndl(params[1], pContext, &query, &db)) != HandleError_None))
1.118 {
1.119 - return pContext->ThrowNativeError("Invalid statement or db Handle %x (error: %d)", params[1], err);
1.120 + return pContext->ThrowNativeError("Invalid statement, db, or query Handle %x (error: %d)", params[1], err);
1.121 }
1.122
1.123 - if (db)
1.124 +
1.125 + if (stmt)
1.126 + {
1.127 + return stmt->GetAffectedRows();
1.128 + }
1.129 + else if (query)
1.130 + {
1.131 + return db->GetAffectedRowsForQuery(query);
1.132 + }
1.133 + else if (db)
1.134 {
1.135 return db->GetAffectedRows();
1.136 - } else if (stmt) {
1.137 - return stmt->GetAffectedRows();
1.138 }
1.139
1.140 - return pContext->ThrowNativeError("Unknown error reading db/stmt handles");
1.141 + return pContext->ThrowNativeError("Unknown error reading db/stmt/query handles");
1.142 }
1.143
1.144 static cell_t SQL_GetInsertId(IPluginContext *pContext, const cell_t *params)
1.145 {
1.146 IDatabase *db = NULL;
1.147 + IQuery *query = NULL;
1.148 IPreparedQuery *stmt = NULL;
1.149 HandleError err;
1.150
1.151 - if ((err = ReadDbOrStmtHndl(params[1], pContext, &db, &stmt)) != HandleError_None)
1.152 + if (((err = ReadDbOrStmtHndl(params[1], pContext, &db, &stmt)) != HandleError_None)
1.153 + && ((err = ReadQueryAndDbHndl(params[1], pContext, &query, &db)) != HandleError_None))
1.154 {
1.155 - return pContext->ThrowNativeError("Invalid statement or db Handle %x (error: %d)", params[1], err);
1.156 + return pContext->ThrowNativeError("Invalid statement, db, or query Handle %x (error: %d)", params[1], err);
1.157 }
1.158
1.159 - if (db)
1.160 + if (query)
1.161 + {
1.162 + return db->GetInsertIDForQuery(query);
1.163 + }
1.164 + else if (db)
1.165 {
1.166 return db->GetInsertID();
1.167 - } else if (stmt) {
1.168 + }
1.169 + else if (stmt)
1.170 + {
1.171 return stmt->GetInsertID();
1.172 }
1.173
1.174 - return pContext->ThrowNativeError("Unknown error reading db/stmt handles");
1.175 + return pContext->ThrowNativeError("Unknown error reading db/stmt/query handles");
1.176 }
1.177
1.178 static cell_t SQL_GetError(IPluginContext *pContext, const cell_t *params)
1.179 @@ -682,10 +738,14 @@
1.180 return BAD_HANDLE;
1.181 }
1.182
1.183 - Handle_t hndl = g_HandleSys.CreateHandle(hQueryType, qr, pContext->GetIdentity(), g_pCoreIdent, NULL);
1.184 + CombinedQuery *c = new CombinedQuery;
1.185 + c->query = qr;
1.186 + c->db = db;
1.187 + Handle_t hndl = g_HandleSys.CreateHandle(hCombinedQueryType, c, pContext->GetIdentity(), g_pCoreIdent, NULL);
1.188 if (hndl == BAD_HANDLE)
1.189 {
1.190 qr->Destroy();
1.191 + delete c;
1.192 return BAD_HANDLE;
1.193 }
1.194