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