1.1 --- a/core/smn_database.cpp Fri Mar 28 06:21:34 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,1306 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#include "sm_globals.h"
1.36 -#include "HandleSys.h"
1.37 -#include "Database.h"
1.38 -#include "ExtensionSys.h"
1.39 -#include "PluginSys.h"
1.40 -#include "sm_stringutil.h"
1.41 -
1.42 -HandleType_t hQueryType;
1.43 -HandleType_t hStmtType;
1.44 -
1.45 -class DatabaseHelpers :
1.46 - public SMGlobalClass,
1.47 - public IHandleTypeDispatch
1.48 -{
1.49 -public:
1.50 - virtual void OnSourceModAllInitialized()
1.51 - {
1.52 - HandleAccess acc;
1.53 -
1.54 - /* Disable cloning */
1.55 - g_HandleSys.InitAccessDefaults(NULL, &acc);
1.56 - acc.access[HandleAccess_Clone] = HANDLE_RESTRICT_OWNER|HANDLE_RESTRICT_IDENTITY;
1.57 -
1.58 - TypeAccess tacc;
1.59 -
1.60 - g_HandleSys.InitAccessDefaults(&tacc, NULL);
1.61 - tacc.ident = g_pCoreIdent;
1.62 -
1.63 - hQueryType = g_HandleSys.CreateType("IQuery", this, 0, &tacc, &acc, g_pCoreIdent, NULL);
1.64 - hStmtType = g_HandleSys.CreateType("IPreparedQuery", this, hQueryType, &tacc, &acc, g_pCoreIdent, NULL);
1.65 - }
1.66 -
1.67 - virtual void OnSourceModShutdown()
1.68 - {
1.69 - g_HandleSys.RemoveType(hStmtType, g_pCoreIdent);
1.70 - g_HandleSys.RemoveType(hQueryType, g_pCoreIdent);
1.71 - }
1.72 -
1.73 - virtual void OnHandleDestroy(HandleType_t type, void *object)
1.74 - {
1.75 - if (type == hQueryType)
1.76 - {
1.77 - IQuery *query = (IQuery *)object;
1.78 - query->Destroy();
1.79 - } else if (type == hStmtType) {
1.80 - IPreparedQuery *query = (IPreparedQuery *)object;
1.81 - query->Destroy();
1.82 - }
1.83 - }
1.84 -} s_DatabaseNativeHelpers;
1.85 -
1.86 -//is this safe for stmt handles? i think since it's single inheritance, it always will be.
1.87 -inline HandleError ReadQueryHndl(Handle_t hndl, IPluginContext *pContext, IQuery **query)
1.88 -{
1.89 - HandleSecurity sec;
1.90 - sec.pOwner = pContext->GetIdentity();
1.91 - sec.pIdentity = g_pCoreIdent;
1.92 -
1.93 - return g_HandleSys.ReadHandle(hndl, hQueryType, &sec, (void **)query);
1.94 -}
1.95 -
1.96 -inline HandleError ReadStmtHndl(Handle_t hndl, IPluginContext *pContext, IPreparedQuery **query)
1.97 -{
1.98 - HandleSecurity sec;
1.99 - sec.pOwner = pContext->GetIdentity();
1.100 - sec.pIdentity = g_pCoreIdent;
1.101 -
1.102 - return g_HandleSys.ReadHandle(hndl, hStmtType, &sec, (void **)query);
1.103 -}
1.104 -
1.105 -inline HandleError ReadDbOrStmtHndl(Handle_t hndl, IPluginContext *pContext, IDatabase **db, IPreparedQuery **query)
1.106 -{
1.107 - HandleError err;
1.108 - if ((err = g_DBMan.ReadHandle(hndl, DBHandle_Database, (void **)db)) == HandleError_Type)
1.109 - {
1.110 - *db = NULL;
1.111 - return ReadStmtHndl(hndl, pContext, query);
1.112 - }
1.113 - return err;
1.114 -}
1.115 -
1.116 -class TQueryOp : public IDBThreadOperation
1.117 -{
1.118 -public:
1.119 - TQueryOp(IDatabase *db, IPluginFunction *pf, const char *query, cell_t data) :
1.120 - m_pDatabase(db), m_pFunction(pf), m_Query(query), m_Data(data),
1.121 - me(g_PluginSys.GetPluginByCtx(pf->GetParentContext()->GetContext())),
1.122 - m_pQuery(NULL)
1.123 - {
1.124 - /* We always increase the reference count because this is potentially
1.125 - * asynchronous. Otherwise the original handle could be closed while
1.126 - * we're still latched onto it.
1.127 - */
1.128 - m_pDatabase->IncReferenceCount();
1.129 -
1.130 - /* Now create our own Handle such that it can only be closed by us.
1.131 - * We allow cloning just in case someone wants to hold onto it.
1.132 - */
1.133 - HandleSecurity sec(me->GetIdentity(), g_pCoreIdent);
1.134 - HandleAccess access;
1.135 - g_HandleSys.InitAccessDefaults(NULL, &access);
1.136 - access.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
1.137 - m_MyHandle = g_HandleSys.CreateHandleEx(g_DBMan.GetDatabaseType(),
1.138 - db,
1.139 - &sec,
1.140 - &access,
1.141 - NULL);
1.142 - }
1.143 - ~TQueryOp()
1.144 - {
1.145 - if (m_pQuery)
1.146 - {
1.147 - m_pQuery->Destroy();
1.148 - }
1.149 -
1.150 - /* Close our Handle if it's valid. */
1.151 - if (m_MyHandle != BAD_HANDLE)
1.152 - {
1.153 - HandleSecurity sec(me->GetIdentity(), g_pCoreIdent);
1.154 - g_HandleSys.FreeHandle(m_MyHandle, &sec);
1.155 - } else {
1.156 - /* Otherwise, there is an open ref to the db */
1.157 - m_pDatabase->Close();
1.158 - }
1.159 - }
1.160 - IdentityToken_t *GetOwner()
1.161 - {
1.162 - return me->GetIdentity();
1.163 - }
1.164 - IDBDriver *GetDriver()
1.165 - {
1.166 - return m_pDatabase->GetDriver();
1.167 - }
1.168 - void RunThreadPart()
1.169 - {
1.170 - m_pDatabase->LockForFullAtomicOperation();
1.171 - m_pQuery = m_pDatabase->DoQuery(m_Query.c_str());
1.172 - if (!m_pQuery)
1.173 - {
1.174 - UTIL_Format(error, sizeof(error), "%s", m_pDatabase->GetError());
1.175 - }
1.176 - m_pDatabase->UnlockFromFullAtomicOperation();
1.177 - }
1.178 - void CancelThinkPart()
1.179 - {
1.180 - m_pFunction->PushCell(BAD_HANDLE);
1.181 - m_pFunction->PushCell(BAD_HANDLE);
1.182 - m_pFunction->PushString("Driver is unloading");
1.183 - m_pFunction->PushCell(m_Data);
1.184 - m_pFunction->Execute(NULL);
1.185 - }
1.186 - void RunThinkPart()
1.187 - {
1.188 - /* Create a Handle for our query */
1.189 - HandleSecurity sec(me->GetIdentity(), g_pCoreIdent);
1.190 - HandleAccess access;
1.191 - g_HandleSys.InitAccessDefaults(NULL, &access);
1.192 - access.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
1.193 -
1.194 - Handle_t qh = BAD_HANDLE;
1.195 -
1.196 - if (m_pQuery)
1.197 - {
1.198 - qh = g_HandleSys.CreateHandle(hQueryType, m_pQuery, me->GetIdentity(), g_pCoreIdent, NULL);
1.199 - if (qh != BAD_HANDLE)
1.200 - {
1.201 - m_pQuery = NULL;
1.202 - } else {
1.203 - UTIL_Format(error, sizeof(error), "Could not alloc handle");
1.204 - }
1.205 - }
1.206 -
1.207 - m_pFunction->PushCell(m_MyHandle);
1.208 - m_pFunction->PushCell(qh);
1.209 - m_pFunction->PushString(qh == BAD_HANDLE ? error : "");
1.210 - m_pFunction->PushCell(m_Data);
1.211 - m_pFunction->Execute(NULL);
1.212 -
1.213 - if (qh != BAD_HANDLE)
1.214 - {
1.215 - g_HandleSys.FreeHandle(qh, &sec);
1.216 - }
1.217 - }
1.218 - void Destroy()
1.219 - {
1.220 - delete this;
1.221 - }
1.222 -private:
1.223 - IDatabase *m_pDatabase;
1.224 - IPluginFunction *m_pFunction;
1.225 - String m_Query;
1.226 - cell_t m_Data;
1.227 - CPlugin *me;
1.228 - IQuery *m_pQuery;
1.229 - char error[255];
1.230 - Handle_t m_MyHandle;
1.231 -};
1.232 -
1.233 -class TConnectOp : public IDBThreadOperation
1.234 -{
1.235 -public:
1.236 - TConnectOp(IPluginFunction *func, IDBDriver *driver, const char *_dbname, cell_t data)
1.237 - {
1.238 - m_pFunction = func;
1.239 - m_pDriver = driver;
1.240 - m_pDatabase = NULL;
1.241 - m_Data = data;
1.242 - error[0] = '\0';
1.243 - strncopy(dbname, _dbname, sizeof(dbname));
1.244 - me = g_PluginSys.GetPluginByCtx(m_pFunction->GetParentContext()->GetContext());
1.245 - }
1.246 - IdentityToken_t *GetOwner()
1.247 - {
1.248 - return me->GetIdentity();
1.249 - }
1.250 - IDBDriver *GetDriver()
1.251 - {
1.252 - return m_pDriver;
1.253 - }
1.254 - void RunThreadPart()
1.255 - {
1.256 - g_DBMan.LockConfig();
1.257 - const DatabaseInfo *pInfo = g_DBMan.FindDatabaseConf(dbname);
1.258 - if (!pInfo)
1.259 - {
1.260 - UTIL_Format(error, sizeof(error), "Could not find database config \"%s\"", dbname);
1.261 - } else {
1.262 - m_pDatabase = m_pDriver->Connect(pInfo, false, error, sizeof(error));
1.263 - }
1.264 - g_DBMan.UnlockConfig();
1.265 - }
1.266 - void CancelThinkPart()
1.267 - {
1.268 - if (m_pDatabase)
1.269 - {
1.270 - m_pDatabase->Close();
1.271 - }
1.272 - m_pFunction->PushCell(BAD_HANDLE);
1.273 - m_pFunction->PushCell(BAD_HANDLE);
1.274 - m_pFunction->PushString("Driver is unloading");
1.275 - m_pFunction->PushCell(m_Data);
1.276 - m_pFunction->Execute(NULL);
1.277 - }
1.278 - void RunThinkPart()
1.279 - {
1.280 - Handle_t hndl = BAD_HANDLE;
1.281 -
1.282 - if (m_pDatabase)
1.283 - {
1.284 - if ((hndl = g_DBMan.CreateHandle(DBHandle_Database, m_pDatabase, me->GetIdentity()))
1.285 - == BAD_HANDLE)
1.286 - {
1.287 - m_pDatabase->Close();
1.288 - UTIL_Format(error, sizeof(error), "Unable to allocate Handle");
1.289 - }
1.290 - }
1.291 -
1.292 - m_pFunction->PushCell(m_pDriver->GetHandle());
1.293 - m_pFunction->PushCell(hndl);
1.294 - m_pFunction->PushString(hndl == BAD_HANDLE ? error : "");
1.295 - m_pFunction->PushCell(m_Data);
1.296 - m_pFunction->Execute(NULL);
1.297 - }
1.298 - void Destroy()
1.299 - {
1.300 - delete this;
1.301 - }
1.302 -private:
1.303 - CPlugin *me;
1.304 - IPluginFunction *m_pFunction;
1.305 - IDBDriver *m_pDriver;
1.306 - IDatabase *m_pDatabase;
1.307 - char dbname[64];
1.308 - char error[255];
1.309 - cell_t m_Data;
1.310 -};
1.311 -
1.312 -static cell_t SQL_Connect(IPluginContext *pContext, const cell_t *params)
1.313 -{
1.314 - char *conf, *err;
1.315 -
1.316 - size_t maxlength = (size_t)params[4];
1.317 - bool persistent = params[2] ? true : false;
1.318 - pContext->LocalToString(params[1], &conf);
1.319 - pContext->LocalToString(params[3], &err);
1.320 -
1.321 - IDBDriver *driver;
1.322 - IDatabase *db;
1.323 - if (!g_DBMan.Connect(conf, &driver, &db, persistent, err, maxlength))
1.324 - {
1.325 - return BAD_HANDLE;
1.326 - }
1.327 -
1.328 - Handle_t hndl = g_DBMan.CreateHandle(DBHandle_Database, db, pContext->GetIdentity());
1.329 - if (!hndl)
1.330 - {
1.331 - db->Close();
1.332 - return BAD_HANDLE;
1.333 - }
1.334 -
1.335 - /* HACK! Add us to the dependency list */
1.336 - CExtension *pExt = g_Extensions.GetExtensionFromIdent(driver->GetIdentity());
1.337 - if (pExt)
1.338 - {
1.339 - g_Extensions.BindChildPlugin(pExt, g_PluginSys.FindPluginByContext(pContext->GetContext()));
1.340 - }
1.341 -
1.342 - return hndl;
1.343 -}
1.344 -
1.345 -static cell_t SQL_TConnect(IPluginContext *pContext, const cell_t *params)
1.346 -{
1.347 - IPluginFunction *pf = pContext->GetFunctionById(params[1]);
1.348 - if (!pf)
1.349 - {
1.350 - return pContext->ThrowNativeError("Function id %x is invalid", params[1]);
1.351 - }
1.352 -
1.353 - char *conf;
1.354 - pContext->LocalToString(params[2], &conf);
1.355 -
1.356 - IDBDriver *driver = NULL;
1.357 - const DatabaseInfo *pInfo = g_DBMan.FindDatabaseConf(conf);
1.358 - char error[255];
1.359 - if (pInfo != NULL)
1.360 - {
1.361 - if (pInfo->driver[0] == '\0')
1.362 - {
1.363 - driver = g_DBMan.GetDefaultDriver();
1.364 - } else {
1.365 - driver = g_DBMan.FindOrLoadDriver(pInfo->driver);
1.366 - }
1.367 - if (!driver)
1.368 - {
1.369 - UTIL_Format(error,
1.370 - sizeof(error),
1.371 - "Could not find driver \"%s\"",
1.372 - pInfo->driver[0] == '\0' ? g_DBMan.GetDefaultDriverName() : pInfo->driver);
1.373 - } else if (!driver->IsThreadSafe()) {
1.374 - UTIL_Format(error,
1.375 - sizeof(error),
1.376 - "Driver \"%s\" is not thread safe!",
1.377 - driver->GetIdentifier());
1.378 - }
1.379 - } else {
1.380 - UTIL_Format(error, sizeof(error), "Could not find database conf \"%s\"", conf);
1.381 - }
1.382 -
1.383 - if (!pInfo || !driver)
1.384 - {
1.385 - pf->PushCell(BAD_HANDLE);
1.386 - pf->PushCell(BAD_HANDLE);
1.387 - pf->PushString(error);
1.388 - pf->PushCell(0);
1.389 - pf->Execute(NULL);
1.390 - return 0;
1.391 - }
1.392 -
1.393 - /* HACK! Add us to the dependency list */
1.394 - CExtension *pExt = g_Extensions.GetExtensionFromIdent(driver->GetIdentity());
1.395 - if (pExt)
1.396 - {
1.397 - g_Extensions.BindChildPlugin(pExt, g_PluginSys.FindPluginByContext(pContext->GetContext()));
1.398 - }
1.399 -
1.400 - /* Finally, add to the thread if we can */
1.401 - TConnectOp *op = new TConnectOp(pf, driver, conf, params[3]);
1.402 - CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
1.403 - if (pPlugin->GetProperty("DisallowDBThreads", NULL)
1.404 - || !g_DBMan.AddToThreadQueue(op, PrioQueue_High))
1.405 - {
1.406 - /* Do everything right now */
1.407 - op->RunThreadPart();
1.408 - op->RunThinkPart();
1.409 - op->Destroy();
1.410 - }
1.411 -
1.412 - return 1;
1.413 -}
1.414 -
1.415 -static cell_t SQL_ConnectEx(IPluginContext *pContext, const cell_t *params)
1.416 -{
1.417 - IDBDriver *driver;
1.418 - if (params[1] == BAD_HANDLE)
1.419 - {
1.420 - if ((driver = g_DBMan.GetDefaultDriver()) == NULL)
1.421 - {
1.422 - return pContext->ThrowNativeError("Could not find any default driver");
1.423 - }
1.424 - } else {
1.425 - HandleError err;
1.426 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Driver, (void **)&driver))
1.427 - != HandleError_None)
1.428 - {
1.429 - return pContext->ThrowNativeError("Invalid driver Handle %x (error: %d)", params[1], err);
1.430 - }
1.431 - }
1.432 -
1.433 - char *host, *user, *pass, *database, *error;
1.434 - size_t maxlength = (size_t)params[7];
1.435 - bool persistent = params[8] ? true : false;
1.436 - unsigned int port = params[9];
1.437 - unsigned int maxTimeout = params[10];
1.438 - pContext->LocalToString(params[2], &host);
1.439 - pContext->LocalToString(params[3], &user);
1.440 - pContext->LocalToString(params[4], &pass);
1.441 - pContext->LocalToString(params[5], &database);
1.442 - pContext->LocalToString(params[6], &error);
1.443 -
1.444 - DatabaseInfo info;
1.445 - info.database = database;
1.446 - info.driver = driver->GetIdentifier();
1.447 - info.host = host;
1.448 - info.maxTimeout = maxTimeout;
1.449 - info.pass = pass;
1.450 - info.port = port;
1.451 - info.user = user;
1.452 -
1.453 - IDatabase *db = driver->Connect(&info, persistent, error, maxlength);
1.454 -
1.455 - if (db)
1.456 - {
1.457 - Handle_t hndl = g_DBMan.CreateHandle(DBHandle_Database, db, pContext->GetIdentity());
1.458 - if (!hndl)
1.459 - {
1.460 - db->Close();
1.461 - return BAD_HANDLE;
1.462 - }
1.463 -
1.464 - /* HACK! Add us to the dependency list */
1.465 - CExtension *pExt = g_Extensions.GetExtensionFromIdent(driver->GetIdentity());
1.466 - if (pExt)
1.467 - {
1.468 - g_Extensions.BindChildPlugin(pExt, g_PluginSys.FindPluginByContext(pContext->GetContext()));
1.469 - }
1.470 -
1.471 - return hndl;
1.472 - }
1.473 -
1.474 - return BAD_HANDLE;
1.475 -}
1.476 -
1.477 -static cell_t SQL_GetDriverIdent(IPluginContext *pContext, const cell_t *params)
1.478 -{
1.479 - IDBDriver *driver;
1.480 - if (params[1] == BAD_HANDLE)
1.481 - {
1.482 - if ((driver = g_DBMan.GetDefaultDriver()) == NULL)
1.483 - {
1.484 - return pContext->ThrowNativeError("Could not find any default driver");
1.485 - }
1.486 - } else {
1.487 - HandleError err;
1.488 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Driver, (void **)&driver))
1.489 - != HandleError_None)
1.490 - {
1.491 - return pContext->ThrowNativeError("Invalid driver Handle %x (error: %d)", params[1], err);
1.492 - }
1.493 - }
1.494 -
1.495 - pContext->StringToLocalUTF8(params[2], params[3], driver->GetIdentifier(), NULL);
1.496 -
1.497 - return 1;
1.498 -}
1.499 -
1.500 -static cell_t SQL_GetDriver(IPluginContext *pContext, const cell_t *params)
1.501 -{
1.502 - char *name;
1.503 - pContext->LocalToString(params[1], &name);
1.504 -
1.505 - IDBDriver *driver = NULL;
1.506 - if (name[0] == '\0')
1.507 - {
1.508 - driver = g_DBMan.GetDefaultDriver();
1.509 - } else {
1.510 - driver = g_DBMan.FindOrLoadDriver(name);
1.511 - }
1.512 -
1.513 - return (driver != NULL) ? driver->GetHandle() : BAD_HANDLE;
1.514 -}
1.515 -
1.516 -static cell_t SQL_GetDriverProduct(IPluginContext *pContext, const cell_t *params)
1.517 -{
1.518 - IDBDriver *driver;
1.519 - if (params[1] == BAD_HANDLE)
1.520 - {
1.521 - if ((driver = g_DBMan.GetDefaultDriver()) == NULL)
1.522 - {
1.523 - return pContext->ThrowNativeError("Could not find any default driver");
1.524 - }
1.525 - } else {
1.526 - HandleError err;
1.527 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Driver, (void **)&driver))
1.528 - != HandleError_None)
1.529 - {
1.530 - return pContext->ThrowNativeError("Invalid driver Handle %x (error: %d)", params[1], err);
1.531 - }
1.532 - }
1.533 -
1.534 - pContext->StringToLocalUTF8(params[2], params[3], driver->GetProductName(), NULL);
1.535 -
1.536 - return 1;
1.537 -}
1.538 -
1.539 -static cell_t SQL_GetAffectedRows(IPluginContext *pContext, const cell_t *params)
1.540 -{
1.541 - IDatabase *db = NULL;
1.542 - IPreparedQuery *stmt = NULL;
1.543 - HandleError err;
1.544 -
1.545 - if ((err = ReadDbOrStmtHndl(params[1], pContext, &db, &stmt)) != HandleError_None)
1.546 - {
1.547 - return pContext->ThrowNativeError("Invalid statement or db Handle %x (error: %d)", params[1], err);
1.548 - }
1.549 -
1.550 - if (db)
1.551 - {
1.552 - return db->GetAffectedRows();
1.553 - } else if (stmt) {
1.554 - return stmt->GetAffectedRows();
1.555 - }
1.556 -
1.557 - return pContext->ThrowNativeError("Unknown error reading db/stmt handles");
1.558 -}
1.559 -
1.560 -static cell_t SQL_GetInsertId(IPluginContext *pContext, const cell_t *params)
1.561 -{
1.562 - IDatabase *db = NULL;
1.563 - IPreparedQuery *stmt = NULL;
1.564 - HandleError err;
1.565 -
1.566 - if ((err = ReadDbOrStmtHndl(params[1], pContext, &db, &stmt)) != HandleError_None)
1.567 - {
1.568 - return pContext->ThrowNativeError("Invalid statement or db Handle %x (error: %d)", params[1], err);
1.569 - }
1.570 -
1.571 - if (db)
1.572 - {
1.573 - return db->GetInsertID();
1.574 - } else if (stmt) {
1.575 - return stmt->GetInsertID();
1.576 - }
1.577 -
1.578 - return pContext->ThrowNativeError("Unknown error reading db/stmt handles");
1.579 -}
1.580 -
1.581 -static cell_t SQL_GetError(IPluginContext *pContext, const cell_t *params)
1.582 -{
1.583 - IDatabase *db = NULL;
1.584 - IPreparedQuery *stmt = NULL;
1.585 - HandleError err;
1.586 -
1.587 - if ((err = ReadDbOrStmtHndl(params[1], pContext, &db, &stmt)) != HandleError_None)
1.588 - {
1.589 - return pContext->ThrowNativeError("Invalid statement or db Handle %x (error: %d)", params[1], err);
1.590 - }
1.591 -
1.592 - const char *error = "";
1.593 - if (db)
1.594 - {
1.595 - error = db->GetError();
1.596 - } else if (stmt) {
1.597 - error = stmt->GetError();
1.598 - }
1.599 -
1.600 - if (error[0] == '\0')
1.601 - {
1.602 - return false;
1.603 - }
1.604 -
1.605 - pContext->StringToLocalUTF8(params[2], params[3], error, NULL);
1.606 -
1.607 - return 1;
1.608 -}
1.609 -
1.610 -static cell_t SQL_QuoteString(IPluginContext *pContext, const cell_t *params)
1.611 -{
1.612 - IDatabase *db = NULL;
1.613 - HandleError err;
1.614 -
1.615 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db))
1.616 - != HandleError_None)
1.617 - {
1.618 - return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err);
1.619 - }
1.620 -
1.621 - char *input, *output;
1.622 - size_t maxlength = (size_t)params[4];
1.623 - pContext->LocalToString(params[2], &input);
1.624 - pContext->LocalToString(params[3], &output);
1.625 -
1.626 - size_t written;
1.627 - bool s = db->QuoteString(input, output, maxlength, &written);
1.628 -
1.629 - cell_t *addr;
1.630 - pContext->LocalToPhysAddr(params[5], &addr);
1.631 - *addr = (cell_t)written;
1.632 -
1.633 - return s ? 1 : 0;
1.634 -}
1.635 -
1.636 -static cell_t SQL_FastQuery(IPluginContext *pContext, const cell_t *params)
1.637 -{
1.638 - IDatabase *db = NULL;
1.639 - HandleError err;
1.640 -
1.641 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db))
1.642 - != HandleError_None)
1.643 - {
1.644 - return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err);
1.645 - }
1.646 -
1.647 - char *query;
1.648 - pContext->LocalToString(params[2], &query);
1.649 -
1.650 - return db->DoSimpleQuery(query) ? 1 : 0;
1.651 -}
1.652 -
1.653 -static cell_t SQL_Query(IPluginContext *pContext, const cell_t *params)
1.654 -{
1.655 - IDatabase *db = NULL;
1.656 - HandleError err;
1.657 -
1.658 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db))
1.659 - != HandleError_None)
1.660 - {
1.661 - return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err);
1.662 - }
1.663 -
1.664 - char *query;
1.665 - pContext->LocalToString(params[2], &query);
1.666 -
1.667 - IQuery *qr = db->DoQuery(query);
1.668 -
1.669 - if (!qr)
1.670 - {
1.671 - return BAD_HANDLE;
1.672 - }
1.673 -
1.674 - Handle_t hndl = g_HandleSys.CreateHandle(hQueryType, qr, pContext->GetIdentity(), g_pCoreIdent, NULL);
1.675 - if (hndl == BAD_HANDLE)
1.676 - {
1.677 - qr->Destroy();
1.678 - return BAD_HANDLE;
1.679 - }
1.680 -
1.681 - return hndl;
1.682 -}
1.683 -
1.684 -static cell_t SQL_TQuery(IPluginContext *pContext, const cell_t *params)
1.685 -{
1.686 - IDatabase *db = NULL;
1.687 - HandleError err;
1.688 -
1.689 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db))
1.690 - != HandleError_None)
1.691 - {
1.692 - return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err);
1.693 - }
1.694 -
1.695 - if (!db->GetDriver()->IsThreadSafe())
1.696 - {
1.697 - return pContext->ThrowNativeError("Driver \"%s\" is not thread safe!", db->GetDriver()->GetIdentifier());
1.698 - }
1.699 -
1.700 - IPluginFunction *pf = pContext->GetFunctionById(params[2]);
1.701 - if (!pf)
1.702 - {
1.703 - return pContext->ThrowNativeError("Function id %x is invalid", params[2]);
1.704 - }
1.705 -
1.706 - char *query;
1.707 - pContext->LocalToString(params[3], &query);
1.708 -
1.709 - cell_t data = params[4];
1.710 - PrioQueueLevel level = PrioQueue_Normal;
1.711 - if (params[5] == (cell_t)PrioQueue_High)
1.712 - {
1.713 - level = PrioQueue_High;
1.714 - } else if (params[5] == (cell_t)PrioQueue_Low) {
1.715 - level = PrioQueue_Low;
1.716 - }
1.717 -
1.718 - CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
1.719 -
1.720 - TQueryOp *op = new TQueryOp(db, pf, query, data);
1.721 - if (pPlugin->GetProperty("DisallowDBThreads", NULL)
1.722 - || !g_DBMan.AddToThreadQueue(op, level))
1.723 - {
1.724 - /* Do everything right now */
1.725 - op->RunThreadPart();
1.726 - op->RunThinkPart();
1.727 - op->Destroy();
1.728 - }
1.729 -
1.730 - return 1;
1.731 -}
1.732 -
1.733 -static cell_t SQL_LockDatabase(IPluginContext *pContext, const cell_t *params)
1.734 -{
1.735 - IDatabase *db = NULL;
1.736 - HandleError err;
1.737 -
1.738 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db))
1.739 - != HandleError_None)
1.740 - {
1.741 - return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err);
1.742 - }
1.743 -
1.744 - db->LockForFullAtomicOperation();
1.745 -
1.746 - return 1;
1.747 -}
1.748 -
1.749 -static cell_t SQL_UnlockDatabase(IPluginContext *pContext, const cell_t *params)
1.750 -{
1.751 - IDatabase *db = NULL;
1.752 - HandleError err;
1.753 -
1.754 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db))
1.755 - != HandleError_None)
1.756 - {
1.757 - return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err);
1.758 - }
1.759 -
1.760 - db->UnlockFromFullAtomicOperation();
1.761 -
1.762 - return 1;
1.763 -}
1.764 -
1.765 -static cell_t SQL_PrepareQuery(IPluginContext *pContext, const cell_t *params)
1.766 -{
1.767 - IDatabase *db = NULL;
1.768 - HandleError err;
1.769 -
1.770 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db))
1.771 - != HandleError_None)
1.772 - {
1.773 - return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err);
1.774 - }
1.775 -
1.776 - char *query, *error;
1.777 - size_t maxlength = (size_t)params[4];
1.778 - pContext->LocalToString(params[2], &query);
1.779 - pContext->LocalToString(params[3], &error);
1.780 -
1.781 - IPreparedQuery *qr = db->PrepareQuery(query, error, maxlength);
1.782 -
1.783 - if (!qr)
1.784 - {
1.785 - return BAD_HANDLE;
1.786 - }
1.787 -
1.788 - Handle_t hndl = g_HandleSys.CreateHandle(hStmtType, qr, pContext->GetIdentity(), g_pCoreIdent, NULL);
1.789 - if (hndl == BAD_HANDLE)
1.790 - {
1.791 - qr->Destroy();
1.792 - return BAD_HANDLE;
1.793 - }
1.794 -
1.795 - return hndl;
1.796 -}
1.797 -
1.798 -static cell_t SQL_FetchMoreResults(IPluginContext *pContext, const cell_t *params)
1.799 -{
1.800 - IQuery *query;
1.801 - HandleError err;
1.802 -
1.803 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.804 - {
1.805 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.806 - }
1.807 -
1.808 - return query->FetchMoreResults() ? 1 : 0;
1.809 -}
1.810 -
1.811 -static cell_t SQL_HasResultSet(IPluginContext *pContext, const cell_t *params)
1.812 -{
1.813 - IQuery *query;
1.814 - HandleError err;
1.815 -
1.816 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.817 - {
1.818 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.819 - }
1.820 -
1.821 - return query->GetResultSet() != NULL ? true : false;
1.822 -}
1.823 -
1.824 -static cell_t SQL_GetRowCount(IPluginContext *pContext, const cell_t *params)
1.825 -{
1.826 - IQuery *query;
1.827 - HandleError err;
1.828 -
1.829 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.830 - {
1.831 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.832 - }
1.833 -
1.834 - IResultSet *rs = query->GetResultSet();
1.835 - if (!rs)
1.836 - {
1.837 - return 0;
1.838 - }
1.839 -
1.840 - return rs->GetRowCount();
1.841 -}
1.842 -
1.843 -static cell_t SQL_GetFieldCount(IPluginContext *pContext, const cell_t *params)
1.844 -{
1.845 - IQuery *query;
1.846 - HandleError err;
1.847 -
1.848 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.849 - {
1.850 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.851 - }
1.852 -
1.853 - IResultSet *rs = query->GetResultSet();
1.854 - if (!rs)
1.855 - {
1.856 - return 0;
1.857 - }
1.858 -
1.859 - return rs->GetFieldCount();
1.860 -}
1.861 -
1.862 -static cell_t SQL_FieldNumToName(IPluginContext *pContext, const cell_t *params)
1.863 -{
1.864 - IQuery *query;
1.865 - HandleError err;
1.866 -
1.867 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.868 - {
1.869 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.870 - }
1.871 -
1.872 - IResultSet *rs = query->GetResultSet();
1.873 - if (!rs)
1.874 - {
1.875 - return pContext->ThrowNativeError("No current result set");
1.876 - }
1.877 -
1.878 - unsigned int field = params[2];
1.879 -
1.880 - const char *fldname;
1.881 - if ((fldname = rs->FieldNumToName(field)) == NULL)
1.882 - {
1.883 - return pContext->ThrowNativeError("Invalid field index %d", field);
1.884 - }
1.885 -
1.886 - pContext->StringToLocalUTF8(params[3], params[4], fldname, NULL);
1.887 -
1.888 - return 1;
1.889 -}
1.890 -
1.891 -static cell_t SQL_FieldNameToNum(IPluginContext *pContext, const cell_t *params)
1.892 -{
1.893 - IQuery *query;
1.894 - HandleError err;
1.895 -
1.896 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.897 - {
1.898 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.899 - }
1.900 -
1.901 - IResultSet *rs = query->GetResultSet();
1.902 - if (!rs)
1.903 - {
1.904 - return pContext->ThrowNativeError("No current result set");
1.905 - }
1.906 -
1.907 - char *field;
1.908 - pContext->LocalToString(params[2], &field);
1.909 -
1.910 - cell_t *num;
1.911 - pContext->LocalToPhysAddr(params[3], &num);
1.912 -
1.913 - return rs->FieldNameToNum(field, (unsigned int *)num) ? 1 : 0;
1.914 -}
1.915 -
1.916 -static cell_t SQL_FetchRow(IPluginContext *pContext, const cell_t *params)
1.917 -{
1.918 - IQuery *query;
1.919 - HandleError err;
1.920 -
1.921 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.922 - {
1.923 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.924 - }
1.925 -
1.926 - IResultSet *rs = query->GetResultSet();
1.927 - if (!rs)
1.928 - {
1.929 - return pContext->ThrowNativeError("No current result set");
1.930 - }
1.931 -
1.932 - return (rs->FetchRow() != NULL) ? true : false;
1.933 -}
1.934 -
1.935 -static cell_t SQL_MoreRows(IPluginContext *pContext, const cell_t *params)
1.936 -{
1.937 - IQuery *query;
1.938 - HandleError err;
1.939 -
1.940 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.941 - {
1.942 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.943 - }
1.944 -
1.945 - IResultSet *rs = query->GetResultSet();
1.946 - if (!rs)
1.947 - {
1.948 - return pContext->ThrowNativeError("No current result set");
1.949 - }
1.950 -
1.951 - return rs->MoreRows() ? 1 : 0;
1.952 -}
1.953 -
1.954 -static cell_t SQL_Rewind(IPluginContext *pContext, const cell_t *params)
1.955 -{
1.956 - IQuery *query;
1.957 - HandleError err;
1.958 -
1.959 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.960 - {
1.961 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.962 - }
1.963 -
1.964 - IResultSet *rs = query->GetResultSet();
1.965 - if (!rs)
1.966 - {
1.967 - return pContext->ThrowNativeError("No current result set");
1.968 - }
1.969 -
1.970 - return rs->Rewind() ? 1 : 0;
1.971 -}
1.972 -
1.973 -static cell_t SQL_FetchString(IPluginContext *pContext, const cell_t *params)
1.974 -{
1.975 - IQuery *query;
1.976 - HandleError err;
1.977 -
1.978 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.979 - {
1.980 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.981 - }
1.982 -
1.983 - IResultSet *rs = query->GetResultSet();
1.984 - if (!rs)
1.985 - {
1.986 - return pContext->ThrowNativeError("No current result set");
1.987 - }
1.988 -
1.989 - IResultRow *row = rs->CurrentRow();
1.990 - if (!row)
1.991 - {
1.992 - return pContext->ThrowNativeError("Current result set has no fetched rows");
1.993 - }
1.994 -
1.995 - const char *str;
1.996 - size_t length;
1.997 - DBResult res = row->GetString(params[2], &str, &length);
1.998 -
1.999 - if (res == DBVal_Error)
1.1000 - {
1.1001 - return pContext->ThrowNativeError("Error fetching data from field %d", params[2]);
1.1002 - } else if (res == DBVal_TypeMismatch) {
1.1003 - return pContext->ThrowNativeError("Could not fetch data in field %d as a string", params[2]);
1.1004 - }
1.1005 -
1.1006 - pContext->StringToLocalUTF8(params[3], params[4], str, &length);
1.1007 -
1.1008 - cell_t *addr;
1.1009 - pContext->LocalToPhysAddr(params[5], &addr);
1.1010 - *addr = (cell_t)res;
1.1011 -
1.1012 - return (cell_t)length;
1.1013 -}
1.1014 -
1.1015 -static cell_t SQL_FetchFloat(IPluginContext *pContext, const cell_t *params)
1.1016 -{
1.1017 - IQuery *query;
1.1018 - HandleError err;
1.1019 -
1.1020 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.1021 - {
1.1022 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.1023 - }
1.1024 -
1.1025 - IResultSet *rs = query->GetResultSet();
1.1026 - if (!rs)
1.1027 - {
1.1028 - return pContext->ThrowNativeError("No current result set");
1.1029 - }
1.1030 -
1.1031 - IResultRow *row = rs->CurrentRow();
1.1032 - if (!row)
1.1033 - {
1.1034 - return pContext->ThrowNativeError("Current result set has no fetched rows");
1.1035 - }
1.1036 -
1.1037 - float f;
1.1038 - DBResult res = row->GetFloat(params[2], &f);
1.1039 -
1.1040 - if (res == DBVal_Error)
1.1041 - {
1.1042 - return pContext->ThrowNativeError("Error fetching data from field %d", params[2]);
1.1043 - } else if (res == DBVal_TypeMismatch) {
1.1044 - return pContext->ThrowNativeError("Could not fetch data in field %d as a float", params[2]);
1.1045 - }
1.1046 -
1.1047 - cell_t *addr;
1.1048 - pContext->LocalToPhysAddr(params[3], &addr);
1.1049 - *addr = (cell_t)res;
1.1050 -
1.1051 - return sp_ftoc(f);
1.1052 -}
1.1053 -
1.1054 -static cell_t SQL_FetchInt(IPluginContext *pContext, const cell_t *params)
1.1055 -{
1.1056 - IQuery *query;
1.1057 - HandleError err;
1.1058 -
1.1059 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.1060 - {
1.1061 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.1062 - }
1.1063 -
1.1064 - IResultSet *rs = query->GetResultSet();
1.1065 - if (!rs)
1.1066 - {
1.1067 - return pContext->ThrowNativeError("No current result set");
1.1068 - }
1.1069 -
1.1070 - IResultRow *row = rs->CurrentRow();
1.1071 - if (!row)
1.1072 - {
1.1073 - return pContext->ThrowNativeError("Current result set has no fetched rows");
1.1074 - }
1.1075 -
1.1076 - int iv;
1.1077 - DBResult res = row->GetInt(params[2], &iv);
1.1078 -
1.1079 - if (res == DBVal_Error)
1.1080 - {
1.1081 - return pContext->ThrowNativeError("Error fetching data from field %d", params[2]);
1.1082 - } else if (res == DBVal_TypeMismatch) {
1.1083 - return pContext->ThrowNativeError("Could not fetch data in field %d as an integer", params[2]);
1.1084 - }
1.1085 -
1.1086 - cell_t *addr;
1.1087 - pContext->LocalToPhysAddr(params[3], &addr);
1.1088 - *addr = (cell_t)res;
1.1089 -
1.1090 - return iv;
1.1091 -}
1.1092 -
1.1093 -static cell_t SQL_IsFieldNull(IPluginContext *pContext, const cell_t *params)
1.1094 -{
1.1095 - IQuery *query;
1.1096 - HandleError err;
1.1097 -
1.1098 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.1099 - {
1.1100 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.1101 - }
1.1102 -
1.1103 - IResultSet *rs = query->GetResultSet();
1.1104 - if (!rs)
1.1105 - {
1.1106 - return pContext->ThrowNativeError("No current result set");
1.1107 - }
1.1108 -
1.1109 - IResultRow *row = rs->CurrentRow();
1.1110 - if (!row)
1.1111 - {
1.1112 - return pContext->ThrowNativeError("Current result set has no fetched rows");
1.1113 - }
1.1114 -
1.1115 - if ((unsigned)params[2] >= rs->GetFieldCount())
1.1116 - {
1.1117 - return pContext->ThrowNativeError("Invalid field index %d", params[2]);
1.1118 - }
1.1119 -
1.1120 - return row->IsNull(params[2]) ? 1 : 0;
1.1121 -}
1.1122 -
1.1123 -static cell_t SQL_FetchSize(IPluginContext *pContext, const cell_t *params)
1.1124 -{
1.1125 - IQuery *query;
1.1126 - HandleError err;
1.1127 -
1.1128 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.1129 - {
1.1130 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.1131 - }
1.1132 -
1.1133 - IResultSet *rs = query->GetResultSet();
1.1134 - if (!rs)
1.1135 - {
1.1136 - return pContext->ThrowNativeError("No current result set");
1.1137 - }
1.1138 -
1.1139 - IResultRow *row = rs->CurrentRow();
1.1140 - if (!row)
1.1141 - {
1.1142 - return pContext->ThrowNativeError("Current result set has no fetched rows");
1.1143 - }
1.1144 -
1.1145 - if ((unsigned)params[2] >= rs->GetFieldCount())
1.1146 - {
1.1147 - return pContext->ThrowNativeError("Invalid field index %d", params[2]);
1.1148 - }
1.1149 -
1.1150 - return row->GetDataSize(params[2]);
1.1151 -}
1.1152 -
1.1153 -static cell_t SQL_BindParamInt(IPluginContext *pContext, const cell_t *params)
1.1154 -{
1.1155 - IPreparedQuery *stmt;
1.1156 - HandleError err;
1.1157 -
1.1158 - if ((err = ReadStmtHndl(params[1], pContext, &stmt)) != HandleError_None)
1.1159 - {
1.1160 - return pContext->ThrowNativeError("Invalid statement Handle %x (error: %d)", params[1], err);
1.1161 - }
1.1162 -
1.1163 - if (!stmt->BindParamInt(params[2], params[3], params[4] ? true : false))
1.1164 - {
1.1165 - return pContext->ThrowNativeError("Could not bind parameter %d as an integer", params[2]);
1.1166 - }
1.1167 -
1.1168 - return 1;
1.1169 -}
1.1170 -
1.1171 -static cell_t SQL_BindParamFloat(IPluginContext *pContext, const cell_t *params)
1.1172 -{
1.1173 - IPreparedQuery *stmt;
1.1174 - HandleError err;
1.1175 -
1.1176 - if ((err = ReadStmtHndl(params[1], pContext, &stmt)) != HandleError_None)
1.1177 - {
1.1178 - return pContext->ThrowNativeError("Invalid statement Handle %x (error: %d)", params[1], err);
1.1179 - }
1.1180 -
1.1181 - if (!stmt->BindParamFloat(params[2], sp_ctof(params[3])))
1.1182 - {
1.1183 - return pContext->ThrowNativeError("Could not bind parameter %d as a float", params[2]);
1.1184 - }
1.1185 -
1.1186 - return 1;
1.1187 -}
1.1188 -
1.1189 -static cell_t SQL_BindParamString(IPluginContext *pContext, const cell_t *params)
1.1190 -{
1.1191 - IPreparedQuery *stmt;
1.1192 - HandleError err;
1.1193 -
1.1194 - if ((err = ReadStmtHndl(params[1], pContext, &stmt)) != HandleError_None)
1.1195 - {
1.1196 - return pContext->ThrowNativeError("Invalid statement Handle %x (error: %d)", params[1], err);
1.1197 - }
1.1198 -
1.1199 - char *str;
1.1200 - pContext->LocalToString(params[3], &str);
1.1201 -
1.1202 - if (!stmt->BindParamString(params[2], str, params[4] ? true : false))
1.1203 - {
1.1204 - return pContext->ThrowNativeError("Could not bind parameter %d as a string", params[2]);
1.1205 - }
1.1206 -
1.1207 - return 1;
1.1208 -}
1.1209 -
1.1210 -static cell_t SQL_Execute(IPluginContext *pContext, const cell_t *params)
1.1211 -{
1.1212 - IPreparedQuery *stmt;
1.1213 - HandleError err;
1.1214 -
1.1215 - if ((err = ReadStmtHndl(params[1], pContext, &stmt)) != HandleError_None)
1.1216 - {
1.1217 - return pContext->ThrowNativeError("Invalid statement Handle %x (error: %d)", params[1], err);
1.1218 - }
1.1219 -
1.1220 - return stmt->Execute() ? 1 : 0;
1.1221 -}
1.1222 -
1.1223 -static cell_t SQL_IsSameConnection(IPluginContext *pContext, const cell_t *params)
1.1224 -{
1.1225 - IDatabase *db1=NULL, *db2=NULL;
1.1226 - HandleError err;
1.1227 -
1.1228 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db1))
1.1229 - != HandleError_None)
1.1230 - {
1.1231 - return pContext->ThrowNativeError("Invalid database Handle 1/%x (error: %d)", params[1], err);
1.1232 - }
1.1233 -
1.1234 - if ((err = g_DBMan.ReadHandle(params[2], DBHandle_Database, (void **)&db2))
1.1235 - != HandleError_None)
1.1236 - {
1.1237 - return pContext->ThrowNativeError("Invalid database Handle 2/%x (error: %d)", params[2], err);
1.1238 - }
1.1239 -
1.1240 - return (db1 == db2) ? true : false;
1.1241 -}
1.1242 -
1.1243 -static cell_t SQL_ReadDriver(IPluginContext *pContext, const cell_t *params)
1.1244 -{
1.1245 - IDatabase *db1=NULL;
1.1246 - HandleError err;
1.1247 -
1.1248 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db1))
1.1249 - != HandleError_None)
1.1250 - {
1.1251 - return pContext->ThrowNativeError("Invalid database Handle 1/%x (error: %d)", params[1], err);
1.1252 - }
1.1253 -
1.1254 - IDBDriver *driver = db1->GetDriver();
1.1255 -
1.1256 - pContext->StringToLocalUTF8(params[2], params[3], driver->GetIdentifier(), NULL);
1.1257 -
1.1258 - return driver->GetHandle();
1.1259 -}
1.1260 -
1.1261 -static cell_t SQL_CheckConfig(IPluginContext *pContext, const cell_t *params)
1.1262 -{
1.1263 - char *name;
1.1264 - pContext->LocalToString(params[1], &name);
1.1265 -
1.1266 - return (g_DBMan.FindDatabaseConf(name) != NULL) ? 1 : 0;
1.1267 -}
1.1268 -
1.1269 -REGISTER_NATIVES(dbNatives)
1.1270 -{
1.1271 - {"SQL_BindParamInt", SQL_BindParamInt},
1.1272 - {"SQL_BindParamFloat", SQL_BindParamFloat},
1.1273 - {"SQL_BindParamString", SQL_BindParamString},\
1.1274 - {"SQL_CheckConfig", SQL_CheckConfig},
1.1275 - {"SQL_Connect", SQL_Connect},
1.1276 - {"SQL_ConnectEx", SQL_ConnectEx},
1.1277 - {"SQL_Execute", SQL_Execute},
1.1278 - {"SQL_FastQuery", SQL_FastQuery},
1.1279 - {"SQL_FetchFloat", SQL_FetchFloat},
1.1280 - {"SQL_FetchInt", SQL_FetchInt},
1.1281 - {"SQL_FetchMoreResults", SQL_FetchMoreResults},
1.1282 - {"SQL_FetchRow", SQL_FetchRow},
1.1283 - {"SQL_FetchSize", SQL_FetchSize},
1.1284 - {"SQL_FetchString", SQL_FetchString},
1.1285 - {"SQL_FieldNameToNum", SQL_FieldNameToNum},
1.1286 - {"SQL_FieldNumToName", SQL_FieldNumToName},
1.1287 - {"SQL_GetAffectedRows", SQL_GetAffectedRows},
1.1288 - {"SQL_GetDriver", SQL_GetDriver},
1.1289 - {"SQL_GetDriverIdent", SQL_GetDriverIdent},
1.1290 - {"SQL_GetDriverProduct", SQL_GetDriverProduct},
1.1291 - {"SQL_GetError", SQL_GetError},
1.1292 - {"SQL_GetFieldCount", SQL_GetFieldCount},
1.1293 - {"SQL_GetInsertId", SQL_GetInsertId},
1.1294 - {"SQL_GetRowCount", SQL_GetRowCount},
1.1295 - {"SQL_HasResultSet", SQL_HasResultSet},
1.1296 - {"SQL_IsFieldNull", SQL_IsFieldNull},
1.1297 - {"SQL_IsSameConnection", SQL_IsSameConnection},
1.1298 - {"SQL_LockDatabase", SQL_LockDatabase},
1.1299 - {"SQL_MoreRows", SQL_MoreRows},
1.1300 - {"SQL_PrepareQuery", SQL_PrepareQuery},
1.1301 - {"SQL_Query", SQL_Query},
1.1302 - {"SQL_QuoteString", SQL_QuoteString},
1.1303 - {"SQL_ReadDriver", SQL_ReadDriver},
1.1304 - {"SQL_Rewind", SQL_Rewind},
1.1305 - {"SQL_TConnect", SQL_TConnect},
1.1306 - {"SQL_TQuery", SQL_TQuery},
1.1307 - {"SQL_UnlockDatabase", SQL_UnlockDatabase},
1.1308 - {NULL, NULL},
1.1309 -};