core/smn_database.cpp
changeset 3271 acc921bc57ef
parent 2357 f2db4a4d8e1f
child 3375 42462959f48d
     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