public/IDBDriver.h
author Phong Dang <teame06@gmail.com>
Wed Aug 01 07:29:40 2007 +0000 (2007-08-01)
changeset 1241 2e8046793bc9
parent 1226 478550a4d5ec
child 1330 ab94316bb52b
permissions -rw-r--r--
Added check to make sure player are alive to perform sm_slap, sm_burn, sm_slay.
     1 /**
     2  * vim: set ts=4 :
     3  * ================================================================
     4  * SourceMod
     5  * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
     6  * ================================================================
     7  *
     8  * This program is free software; you can redistribute it and/or 
     9  * modify it under the terms of the GNU General Public License, 
    10  * version 3.0, as published by the Free Software Foundation.
    11  * 
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15  * GNU General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    19  *
    20  * As a special exception, AlliedModders LLC gives you permission to 
    21  * link the code of this program (as well as its derivative works) to 
    22  * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any 
    23  * Game MODs that run on software by the Valve Corporation.  You must 
    24  * obey the GNU General Public License in all respects for all other 
    25  * code used. Additionally, AlliedModders LLC grants this exception 
    26  * to all derivative works. AlliedModders LLC defines further 
    27  * exceptions, found in LICENSE.txt (as of this writing, version 
    28  * JULY-31-2007), or <http://www.sourcemod.net/license.php>.
    29  *
    30  * Version: $Id$
    31  */
    32 
    33 #ifndef _INCLUDE_SOURCEMOD_INTERFACE_DBDRIVER_H_
    34 #define _INCLUDE_SOURCEMOD_INTERFACE_DBDRIVER_H_
    35 
    36 #include <IShareSys.h>
    37 #include <IHandleSys.h>
    38 #include <string.h>
    39 
    40 #define SMINTERFACE_DBI_NAME		"IDBI"
    41 #define SMINTERFACE_DBI_VERSION		5
    42 
    43 namespace SourceMod
    44 {
    45 	/**
    46 	 * @brief Describes a database field value.
    47 	 */
    48 	enum DBResult
    49 	{
    50 		DBVal_Error = 0,		/**< Column number/field is invalid */
    51 		DBVal_TypeMismatch = 1,	/**< You cannot retrieve this data with this type */
    52 		DBVal_Null = 2,			/**< Field has no data (NULL) */
    53 		DBVal_Data = 3,			/**< Field has data */
    54 	};
    55 
    56 	/**
    57 	 * @brief Describes a primitive database type.
    58 	 */
    59 	enum DBType
    60 	{
    61 		DBType_Unknown = 0,		/**< Type could not be inferred */
    62 		DBType_String,			/**< NULL-terminated string (variable length) */
    63 		DBType_Blob,			/**< Raw binary data (variable length) */
    64 		DBType_Integer,			/**< 4-byte signed integer */
    65 		DBType_Float,			/**< 4-byte floating point  */
    66 		DBType_NULL,			/**< NULL (no data) */
    67 		/* --------- */
    68 		DBTypes_TOTAL,			/**< Total number of database types known */
    69 	};
    70 
    71 	/**
    72 	 * @brief Represents a one database result row.
    73 	 *
    74 	 * Note that type mismatches will only occur when type safety is being
    75 	 * enforced.  So far this is only the case for prepared statements in 
    76 	 * MySQL and SQLite.
    77 	 *
    78 	 * Also, it is worth noting that retrieving as raw data will never cause a
    79 	 * type mismatch.
    80 	 */
    81 	class IResultRow
    82 	{
    83 	public:
    84 		/**
    85 		 * @brief Retrieves a database field result as a string.
    86 		 *
    87 		 * For NULL values, the resulting string pointer will be non-NULL but 
    88 		 * empty.  The pointer returned will become invalid after  advancing to
    89 		 * the next row.
    90 		 *
    91 		 * @param columnId		Column to use, starting from 0.
    92 		 * @param pString		Pointer to store a pointer to the string.
    93 		 * @param length		Optional pointer to store the string length.
    94 		 * @return				A DBResult return code.
    95 		 */
    96 		virtual DBResult GetString(unsigned int columnId, const char **pString, size_t *length) =0;
    97 
    98 		/**
    99 		 * @brief Retrieves a database field result as a string, using a 
   100 		 * user-supplied buffer.  If the field is NULL, an empty string
   101 		 * will be copied.
   102 		 *
   103 		 * @param columnId		Column to use, starting from 0.
   104 		 * @param buffer		Buffer to store string in.
   105 		 * @param maxlength		Maximum length of the buffer.
   106 		 * @param written		Optional pointer to store the number of bytes 
   107 		 *						written, excluding the null terminator.
   108 		 * @return				A DBResult return code.
   109 		 */
   110 		virtual DBResult CopyString(unsigned int columnId, 
   111 									char *buffer, 
   112 									size_t maxlength, 
   113 									size_t *written) =0;
   114 		
   115 		/**
   116 		 * @brief Retrieves a database field result as a float.
   117 		 *
   118 		 * For NULL entries, the returned float value will be 0.0.
   119 		 *
   120 		 * @param columnId		Column to use, starting from 0.
   121 		 * @param pFloat		Pointer to a floating point number to set.
   122 		 * @return				A DBResult return code.
   123 		 */
   124 		virtual DBResult GetFloat(unsigned int columnId, float *pFloat) =0;
   125 
   126 		/**
   127 		 * @brief Retrieves a database field result as an integer.
   128 		 *
   129 		 * For NULL entries, the returned integer value will be 0.
   130 		 *
   131 		 * @param columnId		Column to use, starting from 0.
   132 		 * @param pInt			Pointer to an integer number to set.
   133 		 * @return				A DBResult return code.
   134 		 */
   135 		virtual DBResult GetInt(unsigned int columnId, int *pInt) =0;
   136 
   137 		/**
   138 		 * @brief Returns whether or not a field is NULL.
   139 		 *
   140 		 * @param columnId		Column to use, starting from 0.
   141 		 * @return				True if field is NULL, false otherwise.
   142 		 */
   143 		virtual bool IsNull(unsigned int columnId) =0;
   144 
   145 		/**
   146 		 * @brief Returns the size of a field (text/raw/blob) in bytes.
   147 		 * For strings, this returned size will not include the null
   148 		 * terminator.
   149 		 * 
   150 		 * When used on fields that are not of variable length,
   151 		 * the size returned will be the number of bytes required
   152 		 * to store the internal data.  Note that the data size 
   153 		 * will correspond to the ACTUAL data type, not the 
   154 		 * COLUMN type.
   155 		 *
   156 		 * @param columnId		Column to use, starting from 0.
   157 		 * @return				Number of bytes required to store
   158 		 *						the data, or 0 on failure.
   159 		 */
   160 		virtual size_t GetDataSize(unsigned int columnId) =0;
   161 
   162 		/**
   163 		 * @brief Retrieves field data as a raw bitstream.  The pointer returned
   164 		 * will become invalid after advancing to the next row.
   165 		 *
   166 		 * @param columnId		Column to use, starting from 0.
   167 		 * @param pData			Pointer to store the raw bit stream.  If the 
   168 		 *						data is NULL, a NULL pointer will be returned.
   169 		 * @param length		Pointer to store the data length.
   170 		 * @return				A DBResult return code.
   171 		 */
   172 		virtual DBResult GetBlob(unsigned int columnId, const void **pData, size_t *length) =0;
   173 
   174 		/**
   175 		 * @brief Copies field data as a raw bitstream.
   176 		 *
   177 		 * @param columnId		Column to use, starting from 0.
   178 		 * @param buffer		Pointer to copy the data to.  If the data is
   179 		 *						NULL, no data will be copied.
   180 		 * @param maxlength		Maximum length of the buffer.
   181 		 * @param written		Optional pointer to store the number of bytes 
   182 		 *						written.
   183 		 * @return				A DBResult return code.
   184 		 */
   185 		virtual DBResult CopyBlob(unsigned int columnId, void *buffer, size_t maxlength, size_t *written) =0;
   186 	};
   187 
   188 	/**
   189 	 * @brief Describes a set of database results.
   190 	 */
   191 	class IResultSet
   192 	{
   193 	public:
   194 		/**
   195 		 * @brief Returns the number of rows in the set.
   196 		 *
   197 		 * @return				Number of rows in the set.
   198 		 */
   199 		virtual unsigned int GetRowCount() =0;
   200 
   201 		/**
   202 		 * @brief Returns the number of fields in the set.
   203 		 *
   204 		 * @return				Number of fields in the set.
   205 		 */
   206 		virtual unsigned int GetFieldCount() =0;
   207 
   208 		/**
   209 		 * @brief Converts a column number to a column name.
   210 		 *
   211 		 * @param columnId		Column to use, starting from 0.
   212 		 * @return				Pointer to column name, or NULL if not found.
   213 		 */
   214 		virtual const char *FieldNumToName(unsigned int columnId) =0;
   215 
   216 		/**
   217 		 * @brief Converts a column name to a column id.
   218 		 *
   219 		 * @param name			Column name (case sensitive).
   220 		 * @param columnId		Pointer to store the column id.  If the
   221 		 *						name is not found, the value will be
   222 		 *						undefined.
   223 		 * @return				True on success, false if not found.
   224 		 */
   225 		virtual bool FieldNameToNum(const char *name, unsigned int *columnId) =0;
   226 
   227 		/**
   228 		 * @brief Returns if there is still data in the result set.
   229 		 *
   230 		 * @return				False if there is more data to be read, 
   231 		 *						true, otherwise.
   232 		 */
   233 		virtual bool MoreRows() =0;
   234 
   235 		/**
   236 		 * @brief Returns a pointer to the current row and advances
   237 		 * the internal row pointer/counter to the next row available.
   238 		 *
   239 		 * @return				IResultRow pointer to the current row,
   240 		 *						or NULL if there is no more data.
   241 		 */
   242 		virtual IResultRow *FetchRow() =0;
   243 
   244 		/**
   245 		 * @brief Returns a pointer to the current row.
   246 		 *
   247 		 * @return				IResultRow pointer to the current row,
   248 		 *						or NULL if the current row is invalid.
   249 		 */
   250 		virtual IResultRow *CurrentRow() =0;
   251 
   252 		/**
   253 		 * @brief Rewinds back to the beginning of the row iteration.
   254 		 * 
   255 		 * @return				True on success, false otherwise.
   256 		 */
   257 		virtual bool Rewind() =0;
   258 
   259 		/**
   260 		 * @brief Returns a field's type as it should be interpreted
   261 		 * by the user.
   262 		 *
   263 		 * @param field			Field number (starting from 0).
   264 		 * @return				A DBType value.
   265 		 */
   266 		virtual DBType GetFieldType(unsigned int field) =0;
   267 
   268 		/**
   269 		 * @brief Returns a field's type as it will be interpreted
   270 		 * by the GetDataSize() function.  For example, MySQL
   271 		 * for non-prepared queries will store all results as
   272 		 * strings internally.
   273 		 *
   274 		 * @param field			Field number (starting from 0).
   275 		 * @return				A DBType value.
   276 		 */
   277 		virtual DBType GetFieldDataType(unsigned int field) =0;
   278 	};
   279 
   280 	class IDBDriver;
   281 
   282 	class IQuery
   283 	{
   284 	public:
   285 		/**
   286 		 * @brief Returns a pointer to the current result set, if any.  
   287 		 *
   288 		 * @return				An IResultSet pointer on success,
   289 		 *						NULL if no result set exists.
   290 		 */
   291 		virtual IResultSet *GetResultSet() =0;
   292 
   293 		/**
   294 		 * @brief Advances to the next result set if one exists.  This
   295 		 * is for checking for MORE result sets, and should not be used
   296 		 * on the first result set.
   297 		 *
   298 		 * Multiple results only happen in certain cases, such as CALLing
   299 		 * stored procedure that have a SELECTs, where MySQL will return 
   300 		 * both the CALL status and one or more SELECT result sets.  If
   301 		 * you do not process these results, they will be automatically
   302 		 * processed for you.  However, the behaviour of creating a new
   303 		 * query from the same connection while results are left 
   304 		 * unprocessed is undefined, and may result in a dropped 
   305 		 * connection.  Therefore, process all extra results or destroy the
   306 		 * IQuery pointer before starting a new query.
   307 		 *
   308 		 * Again, this only happens in very specific cases, so there is
   309 		 * no need to call this for normal queries.
   310 		 *
   311 		 * After calling this function, GetResultSet() must be called
   312 		 * again to return the result set.  The previous result set
   313 		 * is automatically destroyed and will be unusable.
   314 		 *
   315 		 * @return				True if another result set is
   316 		 *						available, false otherwise.
   317 		 */
   318 		virtual bool FetchMoreResults() =0;
   319 
   320 		/**
   321 		 * @brief Frees resources created by this query.
   322 		 */
   323 		virtual void Destroy() =0;
   324 	};
   325 
   326 	class IPreparedQuery : public IQuery
   327 	{
   328 	public:
   329 		/** 
   330 		 * @brief Binds an integer parameter.
   331 		 *
   332 		 * @param param			Parameter index, starting from 0.
   333 		 * @param num			Number to bind as a value.
   334 		 * @param signd			True to write as signed, false to write as 
   335 		 *						unsigned.
   336 		 * @return				True on success, false otherwise.
   337 		 */
   338 		virtual bool BindParamInt(unsigned int param, int num, bool signd=true) =0;
   339 
   340 		/**
   341 		 * @brief Binds a float parameter.
   342 		 *
   343 		 * @param param			Parameter index, starting from 0.
   344 		 * @param f				Float to bind as a value.
   345 		 * @return				True on success, false otherwise.
   346 		 */
   347 		virtual bool BindParamFloat(unsigned int param, float f) =0;
   348 
   349 		/**
   350 		 * @brief Binds an SQL NULL type as a parameter.
   351 		 *
   352 		 * @param param			Parameter index, starting from 0.
   353 		 * @return				True on success, false otherwise.
   354 		 */
   355 		virtual bool BindParamNull(unsigned int param) =0;
   356 
   357 		/**
   358 		 * @brief Binds a string as a parameter.
   359 		 *
   360 		 * @param param			Parameter index, starting from 0.
   361 		 * @param text			Pointer to a null-terminated string.
   362 		 * @param copy			If true, the pointer is assumed to be
   363 		 *						volatile and a temporary copy may be
   364 		 *						made for safety.
   365 		 * @return				True on success, false otherwise.
   366 		 */
   367 		virtual bool BindParamString(unsigned int param, const char *text, bool copy) =0;
   368 
   369 		/**
   370 		 * @brief Binds a blob of raw data as a parameter.
   371 		 *
   372 		 * @param param			Parameter index, starting from 0.
   373 		 * @param data			Pointer to a blob of memory.
   374 		 * @param length		Number of bytes to copy.
   375 		 * @param copy			If true, the pointer is assumed to be
   376 		 *						volatile and a temporary copy may be
   377 		 *						made for safety.
   378 		 * @return				True on success, false otherwise.
   379 		 */
   380 		virtual bool BindParamBlob(unsigned int param, 
   381 									const void *data, 
   382 									size_t length, 
   383 									bool copy) =0;
   384 
   385 		/**
   386 		 * @brief Executes the query with the currently bound parameters.
   387 
   388 		 * @return				True on success, false otherwise.
   389 		 */
   390 		virtual bool Execute() =0;
   391 
   392 		/**
   393 		 * @brief Returns the last error message from this statement.
   394 		 *
   395 		 * @param errCode		Optional pointer to store the driver-specific
   396 		 *						error code.
   397 		 * @return				Error message string.
   398 		 */
   399 		virtual const char *GetError(int *errCode=NULL) =0;
   400 
   401 		/**
   402 		 * @brief Number of rows affected by the last execute.
   403 		 *
   404 		 * @return				Number of rows affected by the last execute.
   405 		 */
   406 		virtual unsigned int GetAffectedRows() =0;
   407 
   408 		/**
   409 		 * @brief Retrieves the last insert ID on this database connection.
   410 		 *
   411 		 * @return				Row insertion ID of the last execute, if any.
   412 		 */
   413 		virtual unsigned int GetInsertID() =0;
   414 	};
   415 
   416 	class IDBDriver;
   417 
   418 	/**
   419 	 * @brief Encapsulates a database connection.
   420 	 */
   421 	class IDatabase
   422 	{
   423 	public:
   424 		/**
   425 		 * @brief Disconnects the database and frees its associated memory.
   426 		 * Note that the actual object will not be freed until all open 
   427 		 * references have been closed.
   428 		 *
   429 		 * It is guaranteed that an IDatabase pointer won't be destroyed until
   430 		 * all open IQuery or IPreparedQuery pointers are closed.
   431 		 *
   432 		 * This function is thread safe.
   433 		 * 
   434 		 * @return				True if object was destroyed, false if 
   435 		 *						references are remaining.
   436 		 */
   437 		virtual bool Close() =0;
   438 
   439 		/**
   440 		 * @brief Error code and string returned by the last operation on this
   441 		 * connection.
   442 		 *
   443 		 * This function is not thread safe and must be included in any locks.
   444 		 *
   445 		 * @param errorCode		Optional pointer to retrieve an error code.
   446 		 * @return				Error string pointer (empty if none).
   447 		 */
   448 		virtual const char *GetError(int *errorCode=NULL) =0;
   449 
   450 		/**
   451 		 * @brief Prepares and executes a query in one step, and discards
   452 		 * any return data.
   453 		 *
   454 		 * This function is not thread safe and must be included in any locks.
   455 		 *
   456 		 * @param query			Query string.
   457 		 * @return				True on success, false otherwise.
   458 		 */
   459 		virtual bool DoSimpleQuery(const char *query) =0;
   460 
   461 		/**
   462 		 * @brief Prepares and executes a query in one step, and returns
   463 		 * the resultant data set.
   464 		 *
   465 		 * Note: If a query contains more than one result set, each
   466 		 * result set must be processed before a new query is started.
   467 		 *
   468 		 * This function is not thread safe and must be included in any locks.
   469 		 *
   470 		 * @param query			Query string.
   471 		 * @return				IQuery pointer on success, NULL otherwise.
   472 		 */
   473 		virtual IQuery *DoQuery(const char *query) =0;
   474 
   475 		/** 
   476 		 * @brief Prepares a query statement for multiple executions and/or
   477 		 * binding marked parameters (? in MySQL/sqLite, $n in PostgreSQL).
   478 		 *
   479 		 * This function is not thread safe and must be included in any locks.
   480 		 *
   481 		 * @param query			Query string.
   482 		 * @param error			Error buffer.
   483 		 * @param maxlength		Maximum length of the error buffer.
   484 		 * @param errCode		Optional pointer to store a driver-specific error code.
   485 		 * @return				IPreparedQuery pointer on success, NULL
   486 		 *						otherwise.
   487 		 */
   488 		virtual IPreparedQuery *PrepareQuery(const char *query, char *error, size_t maxlength, int *errCode=NULL) =0;
   489 
   490 		/**
   491 		 * Quotes a string for insertion into a query.
   492 		 *
   493 		 * @param str			Source string.
   494 		 * @param buffer		Buffer to store new string (should not overlap source string).
   495 		 * @param maxlen		Maximum length of the output buffer.
   496 		 * @param newSize		Pointer to store the output size.
   497 		 * @return				True on success, false if the output buffer is not big enough.
   498 		 *						If not big enough, the required buffer size is passed through
   499 		 *						newSize.
   500 		 */
   501 		virtual bool QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newSize) =0;
   502 
   503 		/**
   504 		 * @brief Number of rows affected by the last execute.
   505 		 *
   506 		 * This function is not thread safe and must be included in any locks.
   507 		 *
   508 		 * @return				Number of rows affected by the last execute.
   509 		 */
   510 		virtual unsigned int GetAffectedRows() =0;
   511 
   512 		/**
   513 		 * @brief Retrieves the last insert ID on this database connection.
   514 		 *
   515 		 * This function is not thread safe and must be included in any locks.
   516 		 *
   517 		 * @return				Row insertion ID of the last execute, if any.
   518 		 */
   519 		virtual unsigned int GetInsertID() =0;
   520 
   521 		/**
   522 		 * @brief Locks the database for an atomic query+retrieval operation.
   523 		 *
   524 		 * @return				True on success, false if not supported.
   525 		 */
   526 		virtual bool LockForFullAtomicOperation() =0;
   527 
   528 		/**
   529 		 * @brief Unlocks a locked atomic fetch.
   530 		 */
   531 		virtual void UnlockFromFullAtomicOperation() =0;
   532 
   533 		/**
   534 		 * @brief Increases the reference count on the database.
   535 		 *
   536 		 * This function is thread safe.
   537 		 */
   538 		virtual void IncReferenceCount() =0;
   539 
   540 		/**
   541 		 * @brief Returns the parent driver.
   542 		 *
   543 		 * This function is thread safe.
   544 		 */
   545 		virtual IDBDriver *GetDriver() =0;
   546 	};
   547 
   548 	/** 
   549 	 * @brief Describes database connection info.
   550 	 */
   551 	struct DatabaseInfo
   552 	{
   553 		DatabaseInfo()
   554 		{
   555 			dbiVersion = SMINTERFACE_DBI_VERSION;
   556 			port = 0;
   557 			maxTimeout = 0;
   558 		}
   559 		unsigned int dbiVersion;		/**< DBI Version for backwards compatibility */
   560 		const char *host;				/**< Host string */
   561 		const char *database;			/**< Database name string */
   562 		const char *user;				/**< User to authenticate as */
   563 		const char *pass;				/**< Password to authenticate with */
   564 		const char *driver;				/**< Driver to use */
   565 		unsigned int port;				/**< Port to use, 0=default */
   566 		unsigned int maxTimeout;		/**< Maximum timeout, 0=default */
   567 	};
   568 
   569 	/**
   570 	 * @brief Describes an SQL driver.
   571 	 */
   572 	class IDBDriver
   573 	{
   574 	public:
   575 		virtual unsigned int GetDBIVersion()
   576 		{
   577 			return SMINTERFACE_DBI_VERSION;
   578 		}
   579 	public:
   580 		/**
   581 		 * @brief Initiates a database connection.
   582 		 *
   583 		 * Note: Persistent connections should never be created from a thread.
   584 		 * 
   585 		 * @param info			Database connection info pointer.
   586 		 * @param persistent	If true, a previous persistent connection will
   587 		 *						be re-used if possible.
   588 		 * @param error			Buffer to store error message.
   589 		 * @param maxlength		Maximum size of the error buffer.
   590 		 * @return				A new IDatabase pointer, or NULL on failure.
   591 		 */
   592 		virtual IDatabase *Connect(const DatabaseInfo *info, bool persistent, char *error, size_t maxlength) =0;
   593 
   594 		/**
   595 		 * @brief Returns a case insensitive database identifier string.
   596 		 *
   597 		 * @return				String containing an identifier.
   598 		 */
   599 		virtual const char *GetIdentifier() =0;
   600 
   601 		/**
   602 		 * @brief Returns a case sensitive implementation name.
   603 		 *
   604 		 * @return				String containing an implementation name.
   605 		 */
   606 		virtual const char *GetProductName() =0;
   607 
   608 		/**
   609 		 * @brief Retrieves a Handle_t handle of the IDBDriver type.
   610 		 *
   611 		 * @return				A Handle_t handle.
   612 		 */
   613 		virtual Handle_t GetHandle() =0;
   614 
   615 		/**
   616 		 * @brief Returns the driver's controlling identity (must be the same 
   617 		 * as from IExtension::GetIdentity).
   618 		 *
   619 		 * @return				An IdentityToken_t identity.
   620 		 */
   621 		virtual IdentityToken_t *GetIdentity() =0;
   622 
   623 		/**
   624 		 * @brief Returns whether the driver is thread safe.
   625 		 *
   626 		 * @return				True if thread safe, false otherwise.
   627 		 */
   628 		virtual bool IsThreadSafe() =0;
   629 
   630 		/**
   631 		 * @brief Initializes thread safety for the calling thread.
   632 		 *
   633 		 * @return				True on success, false otherwise.
   634 		 */
   635 		virtual bool InitializeThreadSafety() =0;
   636 
   637 		/**
   638 		 * @brief Shuts down thread safety for the calling thread.
   639 		 */
   640 		virtual void ShutdownThreadSafety() =0;
   641 	};
   642 
   643 	/**
   644 	 * @brief Priority queue level.
   645 	 */
   646 	enum PrioQueueLevel
   647 	{
   648 		PrioQueue_High,			/**< High priority */
   649 		PrioQueue_Normal,		/**< Normal priority */
   650 		PrioQueue_Low			/**< Low priority */
   651 	};
   652 
   653 	/**
   654 	 * Specification for a threaded database operation.
   655 	 */
   656 	class IDBThreadOperation
   657 	{
   658 	public:
   659 		/**
   660 		 * @brief Must return the driver this operation is using, or 
   661 		 * NULL if not using any driver.  This is not never inside 
   662 		 * the thread.
   663 		 *
   664 		 * @return			IDBDriver pointer.
   665 		 */
   666 		virtual IDBDriver *GetDriver() =0;
   667 
   668 		/**
   669 		 * @brief Must return the object owning this threaded operation.
   670 		 * This is never called inside the thread.
   671 		 *
   672 		 * @return			IdentityToken_t pointer.
   673 		 */
   674 		virtual IdentityToken_t *GetOwner() =0;
   675 
   676 		/**
   677 		 * @brief Called inside the thread; this is where any blocking
   678 		 * or threaded operations must occur.
   679 		 */
   680 		virtual void RunThreadPart() =0;
   681 
   682 		/**
   683 		 * @brief Called in a server frame after the thread operation 
   684 		 * has completed.  This is the non-threaded completion callback,
   685 		 * which although optional, is useful for pumping results back
   686 		 * to normal game API.
   687 		 */
   688 		virtual void RunThinkPart() =0;
   689 
   690 		/**
   691 		 * @brief If RunThinkPart() is not called, this will be called
   692 		 * instead.  Note that RunThreadPart() is ALWAYS called regardless,
   693 		 * and this is only called when Core requests that the operation
   694 		 * be scrapped (for example, the database driver might be unloading).
   695 		 */
   696 		virtual void CancelThinkPart() =0;
   697 
   698 		/**
   699 		 * @brief Called when the operation is finalized and any resources
   700 		 * can be released.
   701 		 */
   702 		virtual void Destroy() =0;
   703 	};
   704 
   705 	/**
   706 	 * @brief Database-related Handle types.
   707 	 */
   708 	enum DBHandleType
   709 	{
   710 		DBHandle_Driver = 0,		/**< Driver Handle */
   711 		DBHandle_Database = 1,		/**< Database Handle */
   712 	};
   713 
   714 	/**
   715 	 * @brief Describes the DBI manager.
   716 	 */
   717 	class IDBManager : public SMInterface
   718 	{
   719 	public:
   720 		virtual const char *GetInterfaceName() =0;
   721 		virtual unsigned int GetInterfaceVersion() =0;
   722 	public:
   723 		/**
   724 		 * @brief Adds a driver to the DBI system.  Not thread safe.
   725 		 *
   726 		 * @param pDriver		Database driver.
   727 		 */
   728 		virtual void AddDriver(IDBDriver *pDriver) =0;
   729 
   730 		/**
   731 		 * @brief Removes a driver from the DBI system.  Not thread safe.
   732 		 *
   733 		 * @param pDriver		Database driver.
   734 		 */
   735 		virtual void RemoveDriver(IDBDriver *pDriver) =0;
   736 
   737 		/**
   738 		 * @brief Searches for database info by name.  Both the return pointer
   739 		 * and all pointers contained therein should be considered volatile.
   740 		 *
   741 		 * @param name			Named database info.
   742 		 * @return				DatabaseInfo pointer.
   743 		 */
   744 		virtual const DatabaseInfo *FindDatabaseConf(const char *name) =0;
   745 
   746 		/**
   747 		 * @brief Tries to connect to a named database.  Not thread safe.
   748 		 *
   749 		 * @param name			Named database info.
   750 		 * @param pdr			Pointer to store the IDBDriver pointer in.
   751 		 *						If driver is not found, NULL will be stored.
   752 		 * @param pdb			Pointer to store the IDatabase pointer in.
   753 		 *						If connection fails, NULL will be stored.
   754 		 * @param persistent	If true, the dbmanager will attempt to PConnect
   755 		 *						instead of connect.
   756 		 * @param error			Error buffer to store a driver's error message.
   757 		 * @param maxlength		Maximum length of the error buffer.
   758 		 * @return				True on success, false otherwise.
   759 		 */
   760 		virtual bool Connect(const char *name, 
   761 							IDBDriver **pdr, 
   762 							IDatabase **pdb, 
   763 							bool persistent, 
   764 							char *error, 
   765 							size_t maxlength) =0;
   766 
   767 		/**
   768 		 * @brief Returns the number of drivers loaded.  Not thread safe.
   769 		 *
   770 		 * @return				Number of drivers loaded.
   771 		 */
   772 		virtual unsigned int GetDriverCount() =0;
   773 
   774 		/**
   775 		 * @brief Returns a driver by index.  Not thread safe.
   776 		 *
   777 		 * @param index			Driver index, starting from 0.
   778 		 * @return				IDBDriver pointer for the given index.
   779 		 */
   780 		virtual IDBDriver *GetDriver(unsigned int index) =0;
   781 
   782 		/**
   783 		 * @brief Creates a Handle_t of the IDBDriver type.  Not thread safe.
   784 		 *
   785 		 * @param type			A DBHandleType value.
   786 		 * @param ptr			A pointer corrresponding to a DBHandleType 
   787 		 *						object.
   788 		 * @param token			Identity pointer of the owning identity.
   789 		 * @return				A new Handle_t handle, or 0 on failure.
   790 		 */
   791 		virtual Handle_t CreateHandle(DBHandleType type, void *ptr, IdentityToken_t *pToken) =0;
   792 
   793 		/**
   794 		 * @brief Reads an IDBDriver pointer from an IDBDriver handle.  Not 
   795 		 * thread safe.
   796 		 *
   797 		 * @param hndl			Handle_t handle to read.
   798 		 * @param type			A DBHandleType value.
   799 		 * @param ptr			Pointer to store the object pointer.
   800 		 * @return				HandleError value.
   801 		 */
   802 		virtual HandleError ReadHandle(Handle_t hndl, DBHandleType type, void **ptr) =0;
   803 
   804 		/**
   805 		 * @brief Releases an IDBDriver handle.
   806 		 *
   807 		 * @param hndl			Handle_t handle to release.
   808 		 * @param type			A DBHandleType value.
   809 		 * @param token			Identity pointer of the owning identity.
   810 		 * @return				HandleError value.
   811 		 */
   812 		virtual HandleError ReleaseHandle(Handle_t hndl, DBHandleType type, IdentityToken_t *token) =0;
   813 
   814 		/**
   815 		 * @brief Given a driver name, attempts to find it.  If it is not found, SourceMod
   816 		 * will attempt to load it.  This function is not thread safe.
   817 		 *
   818 		 * @param name			Driver identifier name.
   819 		 * @return				IDBDriver pointer on success, NULL otherwise.
   820 		 */
   821 		virtual IDBDriver *FindOrLoadDriver(const char *driver) =0;
   822 
   823 		/**
   824 		 * @brief Returns the default driver, or NULL if none is set.  This 
   825 		 * function is not thread safe.
   826 		 *
   827 		 * @return				IDBDriver pointer on success, NULL otherwise.
   828 		 */
   829 		virtual IDBDriver *GetDefaultDriver() =0;
   830 
   831 		/**
   832 		 * @brief Adds a threaded database operation to the priority queue.
   833 		 * This function is not thread safe.
   834 		 *
   835 		 * @param op			Instance of an IDBThreadOperation.
   836 		 * @param prio			Priority level to run at.
   837 		 * @return				True on success, false on failure.
   838 		 */
   839 		virtual bool AddToThreadQueue(IDBThreadOperation *op, PrioQueueLevel prio) =0;
   840 	};
   841 }
   842 
   843 #endif //_INCLUDE_SOURCEMOD_INTERFACE_DBDRIVER_H_