posted new IDBDriver API - no natives are implemented yet, MySQL extension coming very shortly

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40864
This commit is contained in:
David Anderson 2007-05-29 08:32:12 +00:00
parent be634bb027
commit f48263b9d2
3 changed files with 456 additions and 204 deletions

View File

@ -28,7 +28,22 @@ void DBManager::OnSourceModAllInitialized()
m_DriverType = g_HandleSys.CreateType("IDriver", this, 0, NULL, &sec, g_pCoreIdent, NULL);
m_DatabaseType = g_HandleSys.CreateType("IDatabase", this, 0, NULL, NULL, g_pCoreIdent, NULL);
m_QueryType = g_HandleSys.CreateType("IQuery", this, 0, NULL, NULL, g_pCoreIdent, NULL);
}
void DBManager::OnSourceModShutdown()
{
g_HandleSys.RemoveType(m_DatabaseType, g_pCoreIdent);
g_HandleSys.RemoveType(m_DriverType, g_pCoreIdent);
}
unsigned int DBManager::GetInterfaceVersion()
{
return SMINTERFACE_DBI_VERSION;
}
const char *DBManager::GetInterfaceName()
{
return SMINTERFACE_DBI_NAME;
}
void DBManager::OnHandleDestroy(HandleType_t type, void *object)
@ -39,124 +54,24 @@ void DBManager::OnHandleDestroy(HandleType_t type, void *object)
return;
}
if (g_HandleSys.TypeCheck(type, m_QueryType))
if (g_HandleSys.TypeCheck(type, m_DatabaseType))
{
IQuery *pQuery = (IQuery *)object;
pQuery->Release();
} else if (g_HandleSys.TypeCheck(type, m_DatabaseType)) {
IDatabase *pdb = (IDatabase *)object;
pdb->Close();
}
}
void DBManager::AddDriver(IDBDriver *pDriver, IdentityToken_t *ident)
{
if (!pDriver)
{
return;
}
if (m_drivers.size() >= HANDLESYS_MAX_SUBTYPES)
{
return;
}
db_driver *driver = new db_driver;
driver->driver = pDriver;
driver->ident = ident;
HandleSecurity sec;
sec.pIdentity = ident;
sec.pOwner = g_pCoreIdent;
driver->hDriver = g_HandleSys.CreateHandleEx(m_DriverType, driver, &sec, NULL, NULL);
driver->htDatabase = g_HandleSys.CreateType(NULL, this, m_DatabaseType, NULL, NULL, g_pCoreIdent, NULL);
driver->htQuery = g_HandleSys.CreateType(NULL, this, m_QueryType, NULL, NULL, g_pCoreIdent, NULL);
m_drivers.push_back(driver);
}
void DBManager::RemoveDriver(IDBDriver *pDriver)
{
CVector<db_driver *>::iterator iter;
for (iter = m_drivers.begin();
iter != m_drivers.end();
iter++)
{
if ((*iter)->driver == pDriver)
{
db_driver *driver = (*iter);
HandleSecurity sec;
sec.pIdentity = driver->ident;
sec.pOwner = g_pCoreIdent;
g_HandleSys.RemoveType(driver->htQuery, driver->ident);
g_HandleSys.RemoveType(driver->htDatabase, driver->ident);
g_HandleSys.FreeHandle(driver->hDriver, &sec);
delete driver;
m_drivers.erase(iter);
return;
}
}
}
const char *DBManager::GetInterfaceName()
{
return SMINTERFACE_DBI_NAME;
}
unsigned int DBManager::GetInterfaceVersion()
{
return SMINTERFACE_DBI_VERSION;
}
unsigned int DBManager::GetDriverCount()
{
return (unsigned int)m_drivers.size();
}
IDBDriver *DBManager::GetDriver(unsigned int index, IdentityToken_t **pToken)
{
if (index >= GetDriverCount())
{
return NULL;
}
if (pToken)
{
*pToken = m_drivers[index]->ident;
}
return m_drivers[index]->driver;
}
const DatabaseInfo *DBManager::FindDatabaseConf(const char *name)
{
/* :TODO: implement */
return NULL;
}
bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool persistent)
bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool persistent, char *error, size_t maxlength)
{
const DatabaseInfo *pInfo = FindDatabaseConf(name);
unsigned int count = GetDriverCount();
for (unsigned int i=0; i<count; i++)
for (size_t i=0; i<m_drivers.size(); i++)
{
IDBDriver *driver = GetDriver(i);
if (strcmp(driver->GetIdentifier(), pInfo->driver) == 0)
if (strcasecmp(pInfo->driver, m_drivers[i]->GetIdentifier()) == 0)
{
*pdr = driver;
if (persistent)
{
*pdb = driver->PConnect(pInfo);
} else {
*pdb = driver->Connect(pInfo);
}
*pdr = m_drivers[i];
*pdb = m_drivers[i]->Connect(pInfo, persistent, error, maxlength);
return (*pdb == NULL);
}
}
@ -165,3 +80,81 @@ bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool
return false;
}
void DBManager::AddDriver(IDBDriver *pDriver)
{
m_drivers.push_back(pDriver);
}
void DBManager::RemoveDriver(IDBDriver *pDriver)
{
for (size_t i=0; i<m_drivers.size(); i++)
{
if (m_drivers[i] == pDriver)
{
m_drivers.erase(m_drivers.iterAt(i));
return;
}
}
}
Handle_t DBManager::CreateHandle(DBHandleType dtype, void *ptr, IdentityToken_t *pToken)
{
HandleType_t type = 0;
if (dtype == DBHandle_Driver)
{
type = m_DriverType;
} else if (dtype == DBHandle_Database) {
type = m_DatabaseType;
} else {
return BAD_HANDLE;
}
return g_HandleSys.CreateHandle(type, ptr, pToken, g_pCoreIdent, NULL);
}
HandleError DBManager::ReadHandle(Handle_t hndl, DBHandleType dtype, void **ptr)
{
HandleType_t type = 0;
if (dtype == DBHandle_Driver)
{
type = m_DriverType;
} else if (dtype == DBHandle_Database) {
type = m_DatabaseType;
} else {
return HandleError_Type;
}
HandleSecurity sec(NULL, g_pCoreIdent);
return g_HandleSys.ReadHandle(hndl, dtype, &sec, ptr);
}
HandleError DBManager::ReleaseHandle(Handle_t hndl, DBHandleType type, IdentityToken_t *token)
{
HandleSecurity sec(token, g_pCoreIdent);
return g_HandleSys.FreeHandle(hndl, &sec);
}
unsigned int DBManager::GetDriverCount()
{
return (unsigned int)m_drivers.size();
}
IDBDriver *DBManager::GetDriver(unsigned int index)
{
if (index >= m_drivers.size())
{
return NULL;
}
return m_drivers[index];
}
const DatabaseInfo *DBManager::FindDatabaseConf(const char *name)
{
/* :TODO: */
return NULL;
}

View File

@ -16,46 +16,38 @@
#define _INCLUDE_DATABASE_MANAGER_H_
#include <IDBDriver.h>
#include <IHandleSys.h>
#include "sm_globals.h"
#include <sh_vector.h>
using namespace SourceHook;
struct db_driver
{
IDBDriver *driver;
IdentityToken_t *ident;
HandleType_t htDatabase;
HandleType_t htQuery;
Handle_t hDriver;
};
class DBManager :
public IDBManager,
public SMGlobalClass,
public IHandleTypeDispatch
{
public:
const char *GetInterfaceName();
unsigned int GetInterfaceVersion();
public: //SMGlobalClass
void OnSourceModAllInitialized();
void OnSourceModShutdown();
public: //IHandleTypeDispatch
void OnHandleDestroy(HandleType_t type, void *object);
public: //IDBManager
void AddDriver(IDBDriver *pDriver, IdentityToken_t *ident);
void AddDriver(IDBDriver *pDrivera);
void RemoveDriver(IDBDriver *pDriver);
const DatabaseInfo *FindDatabaseConf(const char *name);
bool Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool persistent);
bool Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool persistent, char *error, size_t maxlength);
unsigned int GetDriverCount();
IDBDriver *GetDriver(unsigned int index, IdentityToken_t **pToken=NULL);
public:
db_driver *GetDriverInfo(unsigned int index);
IDBDriver *GetDriver(unsigned int index);
Handle_t CreateHandle(DBHandleType type, void *ptr, IdentityToken_t *pToken);
HandleError ReadHandle(Handle_t hndl, DBHandleType type, void **ptr);
HandleError ReleaseHandle(Handle_t hndl, DBHandleType type, IdentityToken_t *token);
private:
CVector<db_driver *> m_drivers;
CVector<IDBDriver *> m_drivers;
HandleType_t m_DriverType;
HandleType_t m_DatabaseType;
HandleType_t m_QueryType;
};
extern DBManager g_DBMan;

View File

@ -20,6 +20,7 @@
#define _INCLUDE_SOURCEMOD_INTERFACE_DBDRIVER_H_
#include <IShareSys.h>
#include <IHandleSys.h>
#include <string.h>
#define SMINTERFACE_DBI_NAME "IDBI"
@ -38,8 +39,27 @@ namespace SourceMod
DBVal_Data = 3, /**< Field has data */
};
/**
* @brief Describes a primitive database type.
*/
enum DBType
{
DBType_Unknown = 0, /**< Type could not be inferred */
DBType_String, /**< NULL-terminated string (variable length) */
DBType_Blob, /**< Raw binary data (variable length) */
DBType_Integer, /**< 4-byte signed integer */
DBType_Float, /**< 4-byte floating point */
};
/**
* @brief Represents a one database result row.
*
* Note that type mismatches will only occur when type safety is being
* enforced. So far this is only the case for prepared statements in
* MySQL and SQLite.
*
* Also, it is worth noting that retrieving as raw data will never cause a
* type mismatch.
*/
class IResultRow
{
@ -47,14 +67,33 @@ namespace SourceMod
/**
* @brief Retrieves a database field result as a string.
*
* For NULL values, the resulting string pointer will be non-NULL,
* but empty.
* For NULL values, the resulting string pointer will be non-NULL but
* empty. The pointer returned will become invalid after advancing to
* the next row.
*
* @param columnId Column to use, starting from 0.
* @param pString Pointer to store a pointer to the string.
* @param length Optional pointer to store the string length.
* @return A DBResult return code.
*/
virtual DBResult GetString(unsigned int columnId, const char **pString) =0;
virtual DBResult GetString(unsigned int columnId, const char **pString, size_t *length) =0;
/**
* @brief Retrieves a database field result as a string, using a
* user-supplied buffer. If the field is NULL, an empty string
* will be copied.
*
* @param columnId Column to use, starting from 0.
* @param buffer Buffer to store string in.
* @param maxlength Maximum length of the buffer.
* @param written Optional pointer to store the number of bytes
* written, excluding the null terminator.
* @return A DBResult return code.
*/
virtual DBResult CopyString(unsigned int columnId,
char *buffer,
size_t maxlength,
size_t *written) =0;
/**
* @brief Retrieves a database field result as a float.
@ -82,19 +121,51 @@ namespace SourceMod
* @brief Returns whether or not a field is NULL.
*
* @param columnId Column to use, starting from 0.
* @return A DBResult return code.
* @return True if field is NULL, false otherwise.
*/
virtual DBResult CheckField(unsigned int columnId) =0;
virtual bool IsNull(unsigned int columnId) =0;
/**
* @brief Retrieves field data as a raw bitstream.
* @brief Returns the size of a field (text/raw/blob) in bytes.
* For strings, this returned size will not include the null
* terminator.
*
* When used on fields that are not of variable length,
* the size returned will be the number of bytes required
* to store the internal data. Note that the data size
* will correspond to the ACTUAL data type, not the
* COLUMN type.
*
* @param columnId Column to use, starting from 0.
* @param pData Pointer to store the raw bit stream.
* @return Number of bytes required to store
* the data, or 0 on failure.
*/
virtual size_t GetDataSize(unsigned int columnId) =0;
/**
* @brief Retrieves field data as a raw bitstream. The pointer returned
* will become invalid after advancing to the next row.
*
* @param columnId Column to use, starting from 0.
* @param pData Pointer to store the raw bit stream. If the
* data is NULL, a NULL pointer will be returned.
* @param length Pointer to store the data length.
* @return A DBResult return code.
*/
virtual DBResult GetRaw(unsigned int columnId, void **pData, size_t *length) =0;
virtual DBResult GetBlob(unsigned int columnId, const void **pData, size_t *length) =0;
/**
* @brief Copies field data as a raw bitstream.
*
* @param columnId Column to use, starting from 0.
* @param buffer Pointer to copy the data to. If the data is
* NULL, no data will be copied.
* @param maxlength Maximum length of the buffer.
* @param written Optional pointer to store the number of bytes
* written.
* @return A DBResult return code.
*/
virtual DBResult CopyBlob(unsigned int columnId, void *buffer, size_t maxlength, size_t *written) =0;
};
/**
@ -123,7 +194,7 @@ namespace SourceMod
* @param columnId Column to use, starting from 0.
* @return Pointer to column name, or NULL if not found.
*/
virtual const char *ColNumToName(unsigned int columnId) =0;
virtual const char *FieldNumToName(unsigned int columnId) =0;
/**
* @brief Converts a column name to a column id.
@ -134,7 +205,7 @@ namespace SourceMod
* undefined.
* @return True on success, false if not found.
*/
virtual bool ColNumToName(const char *name, unsigned int *columnId) =0;
virtual bool FieldNameToNum(const char *name, unsigned int *columnId) =0;
/**
* @brief Returns if there is still data in the result set.
@ -142,7 +213,7 @@ namespace SourceMod
* @return False if there is more data to be read,
* true, otherwise.
*/
virtual bool IsFinished() =0;
virtual bool MoreRows() =0;
/**
* @brief Returns a pointer to the current row and advances
@ -159,16 +230,149 @@ namespace SourceMod
* @return True on success, false otherwise.
*/
virtual bool Rewind() =0;
/**
* @brief Returns a field's type as it should be interpreted
* by the user.
*
* @param field Field number (starting from 0).
* @return A DBType value.
*/
virtual DBType GetFieldType(unsigned int field) =0;
/**
* @brief Returns a field's type as it will be interpreted
* by the GetDataSize() function. For example, MySQL
* for non-prepared queries will store all results as
* strings internally.
*
* @param field Field number (starting from 0).
* @return A DBType value.
*/
virtual DBType GetFieldDataType(unsigned int field) =0;
};
class IDatabase;
class IDBDriver;
/**
* @brief Encapsulates one database query.
*/
class IQuery
{
public:
/**
* @brief Returns a pointer to the current result set, if any.
*
* @return An IResultSet pointer on success,
* NULL if no result set exists.
*/
virtual IResultSet *GetResultSet() =0;
/**
* @brief Advances to the next result set if one exists. This
* is for checking for MORE result sets, and should not be used
* on the first result set.
*
* Multiple results only happen in certain cases, such as CALLing
* stored procedure that have a SELECTs, where MySQL will return
* both the CALL status and one or more SELECT result sets. If
* you do not process these results, they will be automatically
* processed for you. However, the behaviour of creating a new
* query from the same connection while results are left
* unprocessed is undefined, and may result in a dropped
* connection. Therefore, process all extra results or destroy the
* IQuery pointer before starting a new query.
*
* Again, this only happens in very specific cases, so there is
* no need to call this for normal queries.
*
* After calling this function, GetResultSet() must be called
* again to return the result set. The previous result set
* is automatically destroyed and will be unusable.
*
* @return True if another result set is
* available, false otherwise.
*/
virtual bool FetchMoreResults() =0;
/**
* @brief Frees resources created by this query.
*/
virtual void Destroy() =0;
};
class IPreparedQuery : public IQuery
{
public:
/**
* @brief Binds an integer parameter.
*
* @param param Parameter index, starting from 0.
* @param num Number to bind as a value.
* @param signd True to write as signed, false to write as
* unsigned.
* @return True on success, false otherwise.
*/
virtual bool BindParamInt(unsigned int param, int num, bool signd=true) =0;
/**
* @brief Binds a float parameter.
*
* @param param Parameter index, starting from 0.
* @param f Float to bind as a value.
* @return True on success, false otherwise.
*/
virtual bool BindParamFloat(unsigned int param, float f) =0;
/**
* @brief Binds an SQL NULL type as a parameter.
*
* @param param Parameter index, starting from 0.
* @return True on success, false otherwise.
*/
virtual bool BindParamNull(unsigned int param) =0;
/**
* @brief Binds a string as a parameter.
*
* @param param Parameter index, starting from 0.
* @param text Pointer to a null-terminated string.
* @param copy If true, the pointer is assumed to be
* volatile and a temporary copy may be
* made for safety.
* @return True on success, false otherwise.
*/
virtual bool BindParamString(unsigned int param, const char *text, bool copy) =0;
/**
* @brief Binds a blob of raw data as a parameter.
*
* @param param Parameter index, starting from 0.
* @param data Pointer to a blob of memory.
* @param length Number of bytes to copy.
* @param copy If true, the pointer is assumed to be
* volatile and a temporary copy may be
* made for safety.
* @return True on success, false otherwise.
*/
virtual bool BindParamBlob(unsigned int param,
const void *data,
size_t length,
bool copy) =0;
/**
* @brief Executes the query with the currently bound parameters.
* @return True on success, false otherwise.
*/
virtual bool Execute() =0;
/**
* @brief Returns the last error message from this statement.
*
* @param errCode Optional pointer to store the driver-specific
* error code.
* @return Error message string.
*/
virtual const char *GetError(int *errCode=NULL) =0;
/**
* @brief Number of rows affected by the last execute.
*
@ -177,45 +381,13 @@ namespace SourceMod
virtual unsigned int GetAffectedRows() =0;
/**
* @brief Retrieves the last insert ID of this query, if any.
* @brief Retrieves the last insert ID on this database connection.
*
* @return Row insertion ID of the last execute, if any.
*/
virtual unsigned int GetInsertID() =0;
/**
* @brief Returns the full query string.
*
* @return String containing the original query.
*/
virtual const char *GetQueryString() =0;
/**
* @brief Returns the result set from the last Execute call.
*
* @return IResultSet from the last Execute call.
* Pointer will be NULL if there was no previous
* call, the last call failed, or the last call
* had no result set and Execute() was called with
* retEmptySet=false.
*/
virtual IResultSet *GetResultSet() =0;
/**
* @brief Returns the IDatabase object which created this pointer.
*
* @return IDatabase object which created this pointer.
*/
virtual IDatabase *GetDatabase() =0;
/**
* @brief Releases the resources associated with this query.
*/
virtual void Release() =0;
};
class IDBDriver;
/**
* @brief Encapsulates a database connection.
*/
@ -224,11 +396,18 @@ namespace SourceMod
public:
/**
* @brief Disconnects the database and frees its associated memory.
* If this pointer was received via IDBDriver::PConnect(), Close()
* must be called once for each successful PConnect() call which
* resulted in this pointer.
* Note that the actual object will not be freed until all open
* references have been closed.
*
* It is guaranteed that an IDatabase pointer won't be destroyed until
* all open IQuery or IPreparedQuery pointers are closed.
*
* @param Only pass true if being called from an
* IHandleTypeDispatch destructor.
* @return True if object was destroyed, false if
* references are remaining.
*/
virtual void Close() =0;
virtual bool Close(bool fromHndlSys=false) =0;
/**
* @brief Error code and string returned by the last operation on this
@ -237,18 +416,41 @@ namespace SourceMod
* @param errorCode Optional pointer to retrieve an error code.
* @return Error string pointer (empty if none).
*/
virtual const char *GetLastError(int *errorCode=NULL) =0;
virtual const char *GetError(int *errorCode=NULL) =0;
/**
* @brief Prepares and executes a query in one step, and discards
* any return data.
*
* @param query Query string.
* @return True on success, false otherwise.
*/
virtual bool DoSimpleQuery(const char *query) =0;
/**
* @brief Prepares and executes a query in one step, and returns
* the resulting IQuery pointer.
* the resultant data set.
*
* @param fmt String format to parse.
* @param ... Format parameters.
* @return An IQuery pointer which must be freed, or
* NULL if the query failed.
* Note: If a query contains more than one result set, each
* result set must be processed before a new query is started.
*
* @param query Query string.
* @return IQuery pointer on success, NULL otherwise.
*/
virtual IQuery *DoQuery(const char *fmt, ...) =0;
virtual IQuery *DoQuery(const char *query) =0;
/**
* @brief Prepares a query statement for multiple executions and/or
* binding marked parameters (? in MySQL/sqLite, $n in PostgreSQL).
*
* @param query Query string.
* @param error Error buffer.
* @param maxlength Maximum length of the error buffer.
* @param errCode Optional pointer to store a driver-specific error code.
* @return IPreparedQuery pointer on success, NULL
* otherwise.
*/
virtual IPreparedQuery *PrepareQuery(const char *query, char *error, size_t maxlength, int *errCode=NULL) =0;
/**
* Quotes a string for insertion into a query.
@ -264,11 +466,25 @@ namespace SourceMod
virtual bool QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newSize) =0;
/**
* @brief Returns the parent driver.
* @brief Number of rows affected by the last execute.
*
* @return IDBDriver pointer that created this object.
* @return Number of rows affected by the last execute.
*/
virtual IDBDriver *GetDriver() =0;
virtual unsigned int GetAffectedRows() =0;
/**
* @brief Retrieves the last insert ID on this database connection.
*
* @return Row insertion ID of the last execute, if any.
*/
virtual unsigned int GetInsertID() =0;
/**
* @brief Returns an IDatabase Handle to this IDatabase.
*
* @return Handle_t of type IDatabase.
*/
virtual Handle_t GetHandle() =0;
};
/**
@ -307,35 +523,50 @@ namespace SourceMod
* @brief Initiates a database connection.
*
* @param info Database connection info pointer.
* @param persistent If true, a previous persistent connection will
* be re-used if possible.
* @param error Buffer to store error message.
* @param maxlength Maximum size of the error buffer.
* @return A new IDatabase pointer, or NULL on failure.
*/
virtual IDatabase *Connect(const DatabaseInfo *info) =0;
/**
* @brief Initiates a database connection. If a connection to the given database
* already exists, this will re-use the old connection handle.
*
* @param info Database connection info pointer.
* @return A new IDatabase pointer, or NULL on failure.
*/
virtual IDatabase *PConnect(const DatabaseInfo *info) =0;
virtual IDatabase *Connect(const DatabaseInfo *info, bool persistent, char *error, size_t maxlength) =0;
/**
* @brief Returns a case insensitive database identifier string.
*
* @return String containing an identifier.
*/
virtual const char *GetIdentifier() =0;
/**
* @brief Returns a case sensitive implementation name.
*
* @return String containing an implementation name.
*/
virtual const char *GetProductName() =0;
/**
* @brief Returns the last connection error.
* @brief Retrieves a Handle_t handle of the IDBDriver type.
*
* @param errCode Optional pointer to store a platform-specific error code.
* @return A Handle_t handle.
*/
virtual const char *GetLastError(int *errCode=NULL) =0;
virtual Handle_t GetHandle() =0;
/**
* @brief Returns the driver's controlling identity.
*
* @return An IdentityToken_t identity.
*/
virtual IdentityToken_t *GetIdentity() =0;
};
/**
* @brief Database-related Handle types.
*/
enum DBHandleType
{
DBHandle_Driver = 0, /**< Driver Handle */
DBHandle_Database = 1, /**< Database Handle */
};
/**
@ -352,7 +583,7 @@ namespace SourceMod
*
* @param pDriver Database driver.
*/
virtual void AddDriver(IDBDriver *pDriver, IdentityToken_t *pToken) =0;
virtual void AddDriver(IDBDriver *pDriver) =0;
/**
* @brief Removes a driver from the DBI system.
@ -379,9 +610,16 @@ namespace SourceMod
* If connection fails, NULL will be stored.
* @param persistent If true, the dbmanager will attempt to PConnect
* instead of connect.
* @param error Error buffer to store a driver's error message.
* @param maxlength Maximum length of the error buffer.
* @return True on success, false otherwise.
*/
virtual bool Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool persistent) =0;
virtual bool Connect(const char *name,
IDBDriver **pdr,
IDatabase **pdb,
bool persistent,
char *error,
size_t maxlength) =0;
/**
* @brief Returns the number of drivers loaded.
@ -394,10 +632,39 @@ namespace SourceMod
* @brief Returns a driver by index.
*
* @param index Driver index, starting from 0.
* @param pToken Optional pointer to store the driver's identity token.
* @return IDBDriver pointer for the given index.
*/
virtual IDBDriver *GetDriver(unsigned int index, IdentityToken_t **pToken=NULL) =0;
virtual IDBDriver *GetDriver(unsigned int index) =0;
/**
* @brief Creates a Handle_t of the IDBDriver type.
*
* @param type A DBHandleType value.
* @param ptr A pointer corrresponding to a DBHandleType object.
* @param token Identity pointer of the owning identity.
* @return A new Handle_t handle, or 0 on failure.
*/
virtual Handle_t CreateHandle(DBHandleType type, void *ptr, IdentityToken_t *pToken) =0;
/**
* @brief Reads an IDBDriver pointer from an IDBDriver handle.
*
* @param hndl Handle_t handle to read.
* @param type A DBHandleType value.
* @param ptr Pointer to store the object pointer.
* @return HandleError value.
*/
virtual HandleError ReadHandle(Handle_t hndl, DBHandleType type, void **ptr) =0;
/**
* @brief Releases an IDBDriver handle.
*
* @param hndl Handle_t handle to release.
* @param type A DBHandleType value.
* @param token Identity pointer of the owning identity.
* @return HandleError value.
*/
virtual HandleError ReleaseHandle(Handle_t hndl, DBHandleType type, IdentityToken_t *token) =0;
};
}