1.1 --- a/core/smn_database.cpp Fri Jul 11 06:51:21 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,1321 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2008 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.GetPluginByCtx(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.GetPluginByCtx(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.GetPluginByCtx(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 - if (params[0] >= 3 && params[3] != -1)
1.651 - {
1.652 - return db->DoSimpleQueryEx(query, params[3]) ? 1 : 0;
1.653 - }
1.654 -
1.655 - return db->DoSimpleQuery(query) ? 1 : 0;
1.656 -}
1.657 -
1.658 -static cell_t SQL_Query(IPluginContext *pContext, const cell_t *params)
1.659 -{
1.660 - IDatabase *db = NULL;
1.661 - HandleError err;
1.662 -
1.663 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db))
1.664 - != HandleError_None)
1.665 - {
1.666 - return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err);
1.667 - }
1.668 -
1.669 - char *query;
1.670 - pContext->LocalToString(params[2], &query);
1.671 -
1.672 - IQuery *qr;
1.673 -
1.674 - if (params[0] >= 3 && params[3] != -1)
1.675 - {
1.676 - qr = db->DoQueryEx(query, params[3]);
1.677 - }
1.678 - else
1.679 - {
1.680 - qr = db->DoQuery(query);
1.681 - }
1.682 -
1.683 - if (!qr)
1.684 - {
1.685 - return BAD_HANDLE;
1.686 - }
1.687 -
1.688 - Handle_t hndl = g_HandleSys.CreateHandle(hQueryType, qr, pContext->GetIdentity(), g_pCoreIdent, NULL);
1.689 - if (hndl == BAD_HANDLE)
1.690 - {
1.691 - qr->Destroy();
1.692 - return BAD_HANDLE;
1.693 - }
1.694 -
1.695 - return hndl;
1.696 -}
1.697 -
1.698 -static cell_t SQL_TQuery(IPluginContext *pContext, const cell_t *params)
1.699 -{
1.700 - IDatabase *db = NULL;
1.701 - HandleError err;
1.702 -
1.703 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db))
1.704 - != HandleError_None)
1.705 - {
1.706 - return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err);
1.707 - }
1.708 -
1.709 - if (!db->GetDriver()->IsThreadSafe())
1.710 - {
1.711 - return pContext->ThrowNativeError("Driver \"%s\" is not thread safe!", db->GetDriver()->GetIdentifier());
1.712 - }
1.713 -
1.714 - IPluginFunction *pf = pContext->GetFunctionById(params[2]);
1.715 - if (!pf)
1.716 - {
1.717 - return pContext->ThrowNativeError("Function id %x is invalid", params[2]);
1.718 - }
1.719 -
1.720 - char *query;
1.721 - pContext->LocalToString(params[3], &query);
1.722 -
1.723 - cell_t data = params[4];
1.724 - PrioQueueLevel level = PrioQueue_Normal;
1.725 - if (params[5] == (cell_t)PrioQueue_High)
1.726 - {
1.727 - level = PrioQueue_High;
1.728 - } else if (params[5] == (cell_t)PrioQueue_Low) {
1.729 - level = PrioQueue_Low;
1.730 - }
1.731 -
1.732 - CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
1.733 -
1.734 - TQueryOp *op = new TQueryOp(db, pf, query, data);
1.735 - if (pPlugin->GetProperty("DisallowDBThreads", NULL)
1.736 - || !g_DBMan.AddToThreadQueue(op, level))
1.737 - {
1.738 - /* Do everything right now */
1.739 - op->RunThreadPart();
1.740 - op->RunThinkPart();
1.741 - op->Destroy();
1.742 - }
1.743 -
1.744 - return 1;
1.745 -}
1.746 -
1.747 -static cell_t SQL_LockDatabase(IPluginContext *pContext, const cell_t *params)
1.748 -{
1.749 - IDatabase *db = NULL;
1.750 - HandleError err;
1.751 -
1.752 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db))
1.753 - != HandleError_None)
1.754 - {
1.755 - return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err);
1.756 - }
1.757 -
1.758 - db->LockForFullAtomicOperation();
1.759 -
1.760 - return 1;
1.761 -}
1.762 -
1.763 -static cell_t SQL_UnlockDatabase(IPluginContext *pContext, const cell_t *params)
1.764 -{
1.765 - IDatabase *db = NULL;
1.766 - HandleError err;
1.767 -
1.768 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db))
1.769 - != HandleError_None)
1.770 - {
1.771 - return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err);
1.772 - }
1.773 -
1.774 - db->UnlockFromFullAtomicOperation();
1.775 -
1.776 - return 1;
1.777 -}
1.778 -
1.779 -static cell_t SQL_PrepareQuery(IPluginContext *pContext, const cell_t *params)
1.780 -{
1.781 - IDatabase *db = NULL;
1.782 - HandleError err;
1.783 -
1.784 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db))
1.785 - != HandleError_None)
1.786 - {
1.787 - return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err);
1.788 - }
1.789 -
1.790 - char *query, *error;
1.791 - size_t maxlength = (size_t)params[4];
1.792 - pContext->LocalToString(params[2], &query);
1.793 - pContext->LocalToString(params[3], &error);
1.794 -
1.795 - IPreparedQuery *qr = db->PrepareQuery(query, error, maxlength);
1.796 -
1.797 - if (!qr)
1.798 - {
1.799 - return BAD_HANDLE;
1.800 - }
1.801 -
1.802 - Handle_t hndl = g_HandleSys.CreateHandle(hStmtType, qr, pContext->GetIdentity(), g_pCoreIdent, NULL);
1.803 - if (hndl == BAD_HANDLE)
1.804 - {
1.805 - qr->Destroy();
1.806 - return BAD_HANDLE;
1.807 - }
1.808 -
1.809 - return hndl;
1.810 -}
1.811 -
1.812 -static cell_t SQL_FetchMoreResults(IPluginContext *pContext, const cell_t *params)
1.813 -{
1.814 - IQuery *query;
1.815 - HandleError err;
1.816 -
1.817 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.818 - {
1.819 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.820 - }
1.821 -
1.822 - return query->FetchMoreResults() ? 1 : 0;
1.823 -}
1.824 -
1.825 -static cell_t SQL_HasResultSet(IPluginContext *pContext, const cell_t *params)
1.826 -{
1.827 - IQuery *query;
1.828 - HandleError err;
1.829 -
1.830 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.831 - {
1.832 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.833 - }
1.834 -
1.835 - return query->GetResultSet() != NULL ? true : false;
1.836 -}
1.837 -
1.838 -static cell_t SQL_GetRowCount(IPluginContext *pContext, const cell_t *params)
1.839 -{
1.840 - IQuery *query;
1.841 - HandleError err;
1.842 -
1.843 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.844 - {
1.845 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.846 - }
1.847 -
1.848 - IResultSet *rs = query->GetResultSet();
1.849 - if (!rs)
1.850 - {
1.851 - return 0;
1.852 - }
1.853 -
1.854 - return rs->GetRowCount();
1.855 -}
1.856 -
1.857 -static cell_t SQL_GetFieldCount(IPluginContext *pContext, const cell_t *params)
1.858 -{
1.859 - IQuery *query;
1.860 - HandleError err;
1.861 -
1.862 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.863 - {
1.864 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.865 - }
1.866 -
1.867 - IResultSet *rs = query->GetResultSet();
1.868 - if (!rs)
1.869 - {
1.870 - return 0;
1.871 - }
1.872 -
1.873 - return rs->GetFieldCount();
1.874 -}
1.875 -
1.876 -static cell_t SQL_FieldNumToName(IPluginContext *pContext, const cell_t *params)
1.877 -{
1.878 - IQuery *query;
1.879 - HandleError err;
1.880 -
1.881 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.882 - {
1.883 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.884 - }
1.885 -
1.886 - IResultSet *rs = query->GetResultSet();
1.887 - if (!rs)
1.888 - {
1.889 - return pContext->ThrowNativeError("No current result set");
1.890 - }
1.891 -
1.892 - unsigned int field = params[2];
1.893 -
1.894 - const char *fldname;
1.895 - if ((fldname = rs->FieldNumToName(field)) == NULL)
1.896 - {
1.897 - return pContext->ThrowNativeError("Invalid field index %d", field);
1.898 - }
1.899 -
1.900 - pContext->StringToLocalUTF8(params[3], params[4], fldname, NULL);
1.901 -
1.902 - return 1;
1.903 -}
1.904 -
1.905 -static cell_t SQL_FieldNameToNum(IPluginContext *pContext, const cell_t *params)
1.906 -{
1.907 - IQuery *query;
1.908 - HandleError err;
1.909 -
1.910 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.911 - {
1.912 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.913 - }
1.914 -
1.915 - IResultSet *rs = query->GetResultSet();
1.916 - if (!rs)
1.917 - {
1.918 - return pContext->ThrowNativeError("No current result set");
1.919 - }
1.920 -
1.921 - char *field;
1.922 - pContext->LocalToString(params[2], &field);
1.923 -
1.924 - cell_t *num;
1.925 - pContext->LocalToPhysAddr(params[3], &num);
1.926 -
1.927 - return rs->FieldNameToNum(field, (unsigned int *)num) ? 1 : 0;
1.928 -}
1.929 -
1.930 -static cell_t SQL_FetchRow(IPluginContext *pContext, const cell_t *params)
1.931 -{
1.932 - IQuery *query;
1.933 - HandleError err;
1.934 -
1.935 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.936 - {
1.937 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.938 - }
1.939 -
1.940 - IResultSet *rs = query->GetResultSet();
1.941 - if (!rs)
1.942 - {
1.943 - return pContext->ThrowNativeError("No current result set");
1.944 - }
1.945 -
1.946 - return (rs->FetchRow() != NULL) ? true : false;
1.947 -}
1.948 -
1.949 -static cell_t SQL_MoreRows(IPluginContext *pContext, const cell_t *params)
1.950 -{
1.951 - IQuery *query;
1.952 - HandleError err;
1.953 -
1.954 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.955 - {
1.956 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.957 - }
1.958 -
1.959 - IResultSet *rs = query->GetResultSet();
1.960 - if (!rs)
1.961 - {
1.962 - return pContext->ThrowNativeError("No current result set");
1.963 - }
1.964 -
1.965 - return rs->MoreRows() ? 1 : 0;
1.966 -}
1.967 -
1.968 -static cell_t SQL_Rewind(IPluginContext *pContext, const cell_t *params)
1.969 -{
1.970 - IQuery *query;
1.971 - HandleError err;
1.972 -
1.973 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.974 - {
1.975 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.976 - }
1.977 -
1.978 - IResultSet *rs = query->GetResultSet();
1.979 - if (!rs)
1.980 - {
1.981 - return pContext->ThrowNativeError("No current result set");
1.982 - }
1.983 -
1.984 - return rs->Rewind() ? 1 : 0;
1.985 -}
1.986 -
1.987 -static cell_t SQL_FetchString(IPluginContext *pContext, const cell_t *params)
1.988 -{
1.989 - IQuery *query;
1.990 - HandleError err;
1.991 -
1.992 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.993 - {
1.994 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.995 - }
1.996 -
1.997 - IResultSet *rs = query->GetResultSet();
1.998 - if (!rs)
1.999 - {
1.1000 - return pContext->ThrowNativeError("No current result set");
1.1001 - }
1.1002 -
1.1003 - IResultRow *row = rs->CurrentRow();
1.1004 - if (!row)
1.1005 - {
1.1006 - return pContext->ThrowNativeError("Current result set has no fetched rows");
1.1007 - }
1.1008 -
1.1009 - const char *str;
1.1010 - size_t length;
1.1011 - DBResult res = row->GetString(params[2], &str, &length);
1.1012 -
1.1013 - if (res == DBVal_Error)
1.1014 - {
1.1015 - return pContext->ThrowNativeError("Error fetching data from field %d", params[2]);
1.1016 - } else if (res == DBVal_TypeMismatch) {
1.1017 - return pContext->ThrowNativeError("Could not fetch data in field %d as a string", params[2]);
1.1018 - }
1.1019 -
1.1020 - pContext->StringToLocalUTF8(params[3], params[4], str, &length);
1.1021 -
1.1022 - cell_t *addr;
1.1023 - pContext->LocalToPhysAddr(params[5], &addr);
1.1024 - *addr = (cell_t)res;
1.1025 -
1.1026 - return (cell_t)length;
1.1027 -}
1.1028 -
1.1029 -static cell_t SQL_FetchFloat(IPluginContext *pContext, const cell_t *params)
1.1030 -{
1.1031 - IQuery *query;
1.1032 - HandleError err;
1.1033 -
1.1034 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.1035 - {
1.1036 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.1037 - }
1.1038 -
1.1039 - IResultSet *rs = query->GetResultSet();
1.1040 - if (!rs)
1.1041 - {
1.1042 - return pContext->ThrowNativeError("No current result set");
1.1043 - }
1.1044 -
1.1045 - IResultRow *row = rs->CurrentRow();
1.1046 - if (!row)
1.1047 - {
1.1048 - return pContext->ThrowNativeError("Current result set has no fetched rows");
1.1049 - }
1.1050 -
1.1051 - float f;
1.1052 - DBResult res = row->GetFloat(params[2], &f);
1.1053 -
1.1054 - if (res == DBVal_Error)
1.1055 - {
1.1056 - return pContext->ThrowNativeError("Error fetching data from field %d", params[2]);
1.1057 - } else if (res == DBVal_TypeMismatch) {
1.1058 - return pContext->ThrowNativeError("Could not fetch data in field %d as a float", params[2]);
1.1059 - }
1.1060 -
1.1061 - cell_t *addr;
1.1062 - pContext->LocalToPhysAddr(params[3], &addr);
1.1063 - *addr = (cell_t)res;
1.1064 -
1.1065 - return sp_ftoc(f);
1.1066 -}
1.1067 -
1.1068 -static cell_t SQL_FetchInt(IPluginContext *pContext, const cell_t *params)
1.1069 -{
1.1070 - IQuery *query;
1.1071 - HandleError err;
1.1072 -
1.1073 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.1074 - {
1.1075 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.1076 - }
1.1077 -
1.1078 - IResultSet *rs = query->GetResultSet();
1.1079 - if (!rs)
1.1080 - {
1.1081 - return pContext->ThrowNativeError("No current result set");
1.1082 - }
1.1083 -
1.1084 - IResultRow *row = rs->CurrentRow();
1.1085 - if (!row)
1.1086 - {
1.1087 - return pContext->ThrowNativeError("Current result set has no fetched rows");
1.1088 - }
1.1089 -
1.1090 - int iv;
1.1091 - DBResult res = row->GetInt(params[2], &iv);
1.1092 -
1.1093 - if (res == DBVal_Error)
1.1094 - {
1.1095 - return pContext->ThrowNativeError("Error fetching data from field %d", params[2]);
1.1096 - } else if (res == DBVal_TypeMismatch) {
1.1097 - return pContext->ThrowNativeError("Could not fetch data in field %d as an integer", params[2]);
1.1098 - }
1.1099 -
1.1100 - cell_t *addr;
1.1101 - pContext->LocalToPhysAddr(params[3], &addr);
1.1102 - *addr = (cell_t)res;
1.1103 -
1.1104 - return iv;
1.1105 -}
1.1106 -
1.1107 -static cell_t SQL_IsFieldNull(IPluginContext *pContext, const cell_t *params)
1.1108 -{
1.1109 - IQuery *query;
1.1110 - HandleError err;
1.1111 -
1.1112 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.1113 - {
1.1114 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.1115 - }
1.1116 -
1.1117 - IResultSet *rs = query->GetResultSet();
1.1118 - if (!rs)
1.1119 - {
1.1120 - return pContext->ThrowNativeError("No current result set");
1.1121 - }
1.1122 -
1.1123 - IResultRow *row = rs->CurrentRow();
1.1124 - if (!row)
1.1125 - {
1.1126 - return pContext->ThrowNativeError("Current result set has no fetched rows");
1.1127 - }
1.1128 -
1.1129 - if ((unsigned)params[2] >= rs->GetFieldCount())
1.1130 - {
1.1131 - return pContext->ThrowNativeError("Invalid field index %d", params[2]);
1.1132 - }
1.1133 -
1.1134 - return row->IsNull(params[2]) ? 1 : 0;
1.1135 -}
1.1136 -
1.1137 -static cell_t SQL_FetchSize(IPluginContext *pContext, const cell_t *params)
1.1138 -{
1.1139 - IQuery *query;
1.1140 - HandleError err;
1.1141 -
1.1142 - if ((err = ReadQueryHndl(params[1], pContext, &query)) != HandleError_None)
1.1143 - {
1.1144 - return pContext->ThrowNativeError("Invalid query Handle %x (error: %d)", params[1], err);
1.1145 - }
1.1146 -
1.1147 - IResultSet *rs = query->GetResultSet();
1.1148 - if (!rs)
1.1149 - {
1.1150 - return pContext->ThrowNativeError("No current result set");
1.1151 - }
1.1152 -
1.1153 - IResultRow *row = rs->CurrentRow();
1.1154 - if (!row)
1.1155 - {
1.1156 - return pContext->ThrowNativeError("Current result set has no fetched rows");
1.1157 - }
1.1158 -
1.1159 - if ((unsigned)params[2] >= rs->GetFieldCount())
1.1160 - {
1.1161 - return pContext->ThrowNativeError("Invalid field index %d", params[2]);
1.1162 - }
1.1163 -
1.1164 - return row->GetDataSize(params[2]);
1.1165 -}
1.1166 -
1.1167 -static cell_t SQL_BindParamInt(IPluginContext *pContext, const cell_t *params)
1.1168 -{
1.1169 - IPreparedQuery *stmt;
1.1170 - HandleError err;
1.1171 -
1.1172 - if ((err = ReadStmtHndl(params[1], pContext, &stmt)) != HandleError_None)
1.1173 - {
1.1174 - return pContext->ThrowNativeError("Invalid statement Handle %x (error: %d)", params[1], err);
1.1175 - }
1.1176 -
1.1177 - if (!stmt->BindParamInt(params[2], params[3], params[4] ? true : false))
1.1178 - {
1.1179 - return pContext->ThrowNativeError("Could not bind parameter %d as an integer", params[2]);
1.1180 - }
1.1181 -
1.1182 - return 1;
1.1183 -}
1.1184 -
1.1185 -static cell_t SQL_BindParamFloat(IPluginContext *pContext, const cell_t *params)
1.1186 -{
1.1187 - IPreparedQuery *stmt;
1.1188 - HandleError err;
1.1189 -
1.1190 - if ((err = ReadStmtHndl(params[1], pContext, &stmt)) != HandleError_None)
1.1191 - {
1.1192 - return pContext->ThrowNativeError("Invalid statement Handle %x (error: %d)", params[1], err);
1.1193 - }
1.1194 -
1.1195 - if (!stmt->BindParamFloat(params[2], sp_ctof(params[3])))
1.1196 - {
1.1197 - return pContext->ThrowNativeError("Could not bind parameter %d as a float", params[2]);
1.1198 - }
1.1199 -
1.1200 - return 1;
1.1201 -}
1.1202 -
1.1203 -static cell_t SQL_BindParamString(IPluginContext *pContext, const cell_t *params)
1.1204 -{
1.1205 - IPreparedQuery *stmt;
1.1206 - HandleError err;
1.1207 -
1.1208 - if ((err = ReadStmtHndl(params[1], pContext, &stmt)) != HandleError_None)
1.1209 - {
1.1210 - return pContext->ThrowNativeError("Invalid statement Handle %x (error: %d)", params[1], err);
1.1211 - }
1.1212 -
1.1213 - char *str;
1.1214 - pContext->LocalToString(params[3], &str);
1.1215 -
1.1216 - if (!stmt->BindParamString(params[2], str, params[4] ? true : false))
1.1217 - {
1.1218 - return pContext->ThrowNativeError("Could not bind parameter %d as a string", params[2]);
1.1219 - }
1.1220 -
1.1221 - return 1;
1.1222 -}
1.1223 -
1.1224 -static cell_t SQL_Execute(IPluginContext *pContext, const cell_t *params)
1.1225 -{
1.1226 - IPreparedQuery *stmt;
1.1227 - HandleError err;
1.1228 -
1.1229 - if ((err = ReadStmtHndl(params[1], pContext, &stmt)) != HandleError_None)
1.1230 - {
1.1231 - return pContext->ThrowNativeError("Invalid statement Handle %x (error: %d)", params[1], err);
1.1232 - }
1.1233 -
1.1234 - return stmt->Execute() ? 1 : 0;
1.1235 -}
1.1236 -
1.1237 -static cell_t SQL_IsSameConnection(IPluginContext *pContext, const cell_t *params)
1.1238 -{
1.1239 - IDatabase *db1=NULL, *db2=NULL;
1.1240 - HandleError err;
1.1241 -
1.1242 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db1))
1.1243 - != HandleError_None)
1.1244 - {
1.1245 - return pContext->ThrowNativeError("Invalid database Handle 1/%x (error: %d)", params[1], err);
1.1246 - }
1.1247 -
1.1248 - if ((err = g_DBMan.ReadHandle(params[2], DBHandle_Database, (void **)&db2))
1.1249 - != HandleError_None)
1.1250 - {
1.1251 - return pContext->ThrowNativeError("Invalid database Handle 2/%x (error: %d)", params[2], err);
1.1252 - }
1.1253 -
1.1254 - return (db1 == db2) ? true : false;
1.1255 -}
1.1256 -
1.1257 -static cell_t SQL_ReadDriver(IPluginContext *pContext, const cell_t *params)
1.1258 -{
1.1259 - IDatabase *db1=NULL;
1.1260 - HandleError err;
1.1261 -
1.1262 - if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db1))
1.1263 - != HandleError_None)
1.1264 - {
1.1265 - return pContext->ThrowNativeError("Invalid database Handle 1/%x (error: %d)", params[1], err);
1.1266 - }
1.1267 -
1.1268 - IDBDriver *driver = db1->GetDriver();
1.1269 -
1.1270 - pContext->StringToLocalUTF8(params[2], params[3], driver->GetIdentifier(), NULL);
1.1271 -
1.1272 - return driver->GetHandle();
1.1273 -}
1.1274 -
1.1275 -static cell_t SQL_CheckConfig(IPluginContext *pContext, const cell_t *params)
1.1276 -{
1.1277 - char *name;
1.1278 - pContext->LocalToString(params[1], &name);
1.1279 -
1.1280 - return (g_DBMan.FindDatabaseConf(name) != NULL) ? 1 : 0;
1.1281 -}
1.1282 -
1.1283 -REGISTER_NATIVES(dbNatives)
1.1284 -{
1.1285 - {"SQL_BindParamInt", SQL_BindParamInt},
1.1286 - {"SQL_BindParamFloat", SQL_BindParamFloat},
1.1287 - {"SQL_BindParamString", SQL_BindParamString},\
1.1288 - {"SQL_CheckConfig", SQL_CheckConfig},
1.1289 - {"SQL_Connect", SQL_Connect},
1.1290 - {"SQL_ConnectEx", SQL_ConnectEx},
1.1291 - {"SQL_EscapeString", SQL_QuoteString},
1.1292 - {"SQL_Execute", SQL_Execute},
1.1293 - {"SQL_FastQuery", SQL_FastQuery},
1.1294 - {"SQL_FetchFloat", SQL_FetchFloat},
1.1295 - {"SQL_FetchInt", SQL_FetchInt},
1.1296 - {"SQL_FetchMoreResults", SQL_FetchMoreResults},
1.1297 - {"SQL_FetchRow", SQL_FetchRow},
1.1298 - {"SQL_FetchSize", SQL_FetchSize},
1.1299 - {"SQL_FetchString", SQL_FetchString},
1.1300 - {"SQL_FieldNameToNum", SQL_FieldNameToNum},
1.1301 - {"SQL_FieldNumToName", SQL_FieldNumToName},
1.1302 - {"SQL_GetAffectedRows", SQL_GetAffectedRows},
1.1303 - {"SQL_GetDriver", SQL_GetDriver},
1.1304 - {"SQL_GetDriverIdent", SQL_GetDriverIdent},
1.1305 - {"SQL_GetDriverProduct", SQL_GetDriverProduct},
1.1306 - {"SQL_GetError", SQL_GetError},
1.1307 - {"SQL_GetFieldCount", SQL_GetFieldCount},
1.1308 - {"SQL_GetInsertId", SQL_GetInsertId},
1.1309 - {"SQL_GetRowCount", SQL_GetRowCount},
1.1310 - {"SQL_HasResultSet", SQL_HasResultSet},
1.1311 - {"SQL_IsFieldNull", SQL_IsFieldNull},
1.1312 - {"SQL_IsSameConnection", SQL_IsSameConnection},
1.1313 - {"SQL_LockDatabase", SQL_LockDatabase},
1.1314 - {"SQL_MoreRows", SQL_MoreRows},
1.1315 - {"SQL_PrepareQuery", SQL_PrepareQuery},
1.1316 - {"SQL_Query", SQL_Query},
1.1317 - {"SQL_QuoteString", SQL_QuoteString},
1.1318 - {"SQL_ReadDriver", SQL_ReadDriver},
1.1319 - {"SQL_Rewind", SQL_Rewind},
1.1320 - {"SQL_TConnect", SQL_TConnect},
1.1321 - {"SQL_TQuery", SQL_TQuery},
1.1322 - {"SQL_UnlockDatabase", SQL_UnlockDatabase},
1.1323 - {NULL, NULL},
1.1324 -};