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