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