Merge.
3 * =============================================================================
5 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
6 * =============================================================================
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.
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
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/>.
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>.
32 #ifndef _INCLUDE_SOURCEMOD_INTERFACE_DBDRIVER_H_
33 #define _INCLUDE_SOURCEMOD_INTERFACE_DBDRIVER_H_
35 #include <IShareSys.h>
36 #include <IHandleSys.h>
41 * @brief Defines interfaces for interacting with relational databases.
44 #define SMINTERFACE_DBI_NAME "IDBI"
45 #define SMINTERFACE_DBI_VERSION 8
50 * @brief Describes a database field value.
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 */
61 * @brief Describes a primitive database type.
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) */
72 DBTypes_TOTAL, /**< Total number of database types known */
76 * @brief Represents a one database result row.
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
82 * Also, it is worth noting that retrieving as raw data will never cause a
89 * @brief Retrieves a database field result as a string.
91 * For NULL values, the resulting string pointer will be non-NULL but
92 * empty. The pointer returned will become invalid after advancing to
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.
100 virtual DBResult GetString(unsigned int columnId, const char **pString, size_t *length) =0;
103 * @brief Retrieves a database field result as a string, using a
104 * user-supplied buffer. If the field is NULL, an empty string
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.
114 virtual DBResult CopyString(unsigned int columnId,
120 * @brief Retrieves a database field result as a float.
122 * For NULL entries, the returned float value will be 0.0.
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.
128 virtual DBResult GetFloat(unsigned int columnId, float *pFloat) =0;
131 * @brief Retrieves a database field result as an integer.
133 * For NULL entries, the returned integer value will be 0.
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.
139 virtual DBResult GetInt(unsigned int columnId, int *pInt) =0;
142 * @brief Returns whether or not a field is NULL.
144 * @param columnId Column to use, starting from 0.
145 * @return True if field is NULL, false otherwise.
147 virtual bool IsNull(unsigned int columnId) =0;
150 * @brief Returns the size of a field (text/raw/blob) in bytes.
151 * For strings, this returned size will not include the null
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
160 * @param columnId Column to use, starting from 0.
161 * @return Number of bytes required to store
162 * the data, or 0 on failure.
164 virtual size_t GetDataSize(unsigned int columnId) =0;
167 * @brief Retrieves field data as a raw bitstream. The pointer returned
168 * will become invalid after advancing to the next row.
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.
176 virtual DBResult GetBlob(unsigned int columnId, const void **pData, size_t *length) =0;
179 * @brief Copies field data as a raw bitstream.
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
187 * @return A DBResult return code.
189 virtual DBResult CopyBlob(unsigned int columnId, void *buffer, size_t maxlength, size_t *written) =0;
193 * @brief Describes a set of database results.
199 * @brief Returns the number of rows in the set.
201 * @return Number of rows in the set.
203 virtual unsigned int GetRowCount() =0;
206 * @brief Returns the number of fields in the set.
208 * @return Number of fields in the set.
210 virtual unsigned int GetFieldCount() =0;
213 * @brief Converts a column number to a column name.
215 * @param columnId Column to use, starting from 0.
216 * @return Pointer to column name, or NULL if not found.
218 virtual const char *FieldNumToName(unsigned int columnId) =0;
221 * @brief Converts a column name to a column id.
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
227 * @return True on success, false if not found.
229 virtual bool FieldNameToNum(const char *name, unsigned int *columnId) =0;
232 * @brief Returns if there is still data in the result set.
234 * @return False if there is more data to be read,
237 virtual bool MoreRows() =0;
240 * @brief Returns a pointer to the current row and advances
241 * the internal row pointer/counter to the next row available.
243 * @return IResultRow pointer to the current row,
244 * or NULL if there is no more data.
246 virtual IResultRow *FetchRow() =0;
249 * @brief Returns a pointer to the current row.
251 * @return IResultRow pointer to the current row,
252 * or NULL if the current row is invalid.
254 virtual IResultRow *CurrentRow() =0;
257 * @brief Rewinds back to the beginning of the row iteration.
259 * @return True on success, false otherwise.
261 virtual bool Rewind() =0;
264 * @brief Returns a field's type as it should be interpreted
267 * @param field Field number (starting from 0).
268 * @return A DBType value.
270 virtual DBType GetFieldType(unsigned int field) =0;
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.
278 * @param field Field number (starting from 0).
279 * @return A DBType value.
281 virtual DBType GetFieldDataType(unsigned int field) =0;
290 * @brief Returns a pointer to the current result set, if any.
292 * @return An IResultSet pointer on success,
293 * NULL if no result set exists.
295 virtual IResultSet *GetResultSet() =0;
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.
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.
312 * Again, this only happens in very specific cases, so there is
313 * no need to call this for normal queries.
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.
319 * @return True if another result set is
320 * available, false otherwise.
322 virtual bool FetchMoreResults() =0;
325 * @brief Frees resources created by this query.
327 virtual void Destroy() =0;
330 class IPreparedQuery : public IQuery
334 * @brief Binds an integer parameter.
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
340 * @return True on success, false otherwise.
342 virtual bool BindParamInt(unsigned int param, int num, bool signd=true) =0;
345 * @brief Binds a float parameter.
347 * @param param Parameter index, starting from 0.
348 * @param f Float to bind as a value.
349 * @return True on success, false otherwise.
351 virtual bool BindParamFloat(unsigned int param, float f) =0;
354 * @brief Binds an SQL NULL type as a parameter.
356 * @param param Parameter index, starting from 0.
357 * @return True on success, false otherwise.
359 virtual bool BindParamNull(unsigned int param) =0;
362 * @brief Binds a string as a parameter.
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
369 * @return True on success, false otherwise.
371 virtual bool BindParamString(unsigned int param, const char *text, bool copy) =0;
374 * @brief Binds a blob of raw data as a parameter.
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
382 * @return True on success, false otherwise.
384 virtual bool BindParamBlob(unsigned int param,
390 * @brief Executes the query with the currently bound parameters.
392 * @return True on success, false otherwise.
394 virtual bool Execute() =0;
397 * @brief Returns the last error message from this statement.
399 * @param errCode Optional pointer to store the driver-specific
401 * @return Error message string.
403 virtual const char *GetError(int *errCode=NULL) =0;
406 * @brief Number of rows affected by the last execute.
408 * @return Number of rows affected by the last execute.
410 virtual unsigned int GetAffectedRows() =0;
413 * @brief Retrieves the last insert ID on this database connection.
415 * @return Row insertion ID of the last execute, if any.
417 virtual unsigned int GetInsertID() =0;
423 * @brief Encapsulates a database connection.
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.
433 * It is guaranteed that an IDatabase pointer won't be destroyed until
434 * all open IQuery or IPreparedQuery pointers are closed.
436 * This function is thread safe.
438 * @return True if object was destroyed, false if
439 * references are remaining.
441 virtual bool Close() =0;
444 * @brief Error code and string returned by the last operation on this
447 * This function is not thread safe and must be included in any locks.
449 * @param errorCode Optional pointer to retrieve an error code.
450 * @return Error string pointer (empty if none).
452 virtual const char *GetError(int *errorCode=NULL) =0;
455 * @brief Prepares and executes a query in one step, and discards
458 * This function is not thread safe and must be included in any locks.
460 * @param query Query string.
461 * @return True on success, false otherwise.
463 virtual bool DoSimpleQuery(const char *query) =0;
466 * @brief Prepares and executes a query in one step, and returns
467 * the resultant data set.
469 * Note: If a query contains more than one result set, each
470 * result set must be processed before a new query is started.
472 * This function is not thread safe and must be included in any locks.
474 * @param query Query string.
475 * @return IQuery pointer on success, NULL otherwise.
477 virtual IQuery *DoQuery(const char *query) =0;
480 * @brief Prepares a query statement for multiple executions and/or
481 * binding marked parameters (? in MySQL/sqLite, $n in PostgreSQL).
483 * This function is not thread safe and must be included in any locks.
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
492 virtual IPreparedQuery *PrepareQuery(const char *query, char *error, size_t maxlength, int *errCode=NULL) =0;
495 * Quotes a string for insertion into a query.
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
505 virtual bool QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newSize) =0;
508 * @brief Number of rows affected by the last execute.
510 * This function is not thread safe and must be included in any locks.
512 * @return Number of rows affected by the last execute.
514 virtual unsigned int GetAffectedRows() =0;
517 * @brief Retrieves the last insert ID on this database connection.
519 * This function is not thread safe and must be included in any locks.
521 * @return Row insertion ID of the last execute, if any.
523 virtual unsigned int GetInsertID() =0;
526 * @brief Locks the database for an atomic query+retrieval operation.
528 * @return True on success, false if not supported.
530 virtual bool LockForFullAtomicOperation() =0;
533 * @brief Unlocks a locked atomic fetch.
535 virtual void UnlockFromFullAtomicOperation() =0;
538 * @brief Increases the reference count on the database.
540 * This function is thread safe.
542 virtual void IncReferenceCount() =0;
545 * @brief Returns the parent driver.
547 * This function is thread safe.
549 virtual IDBDriver *GetDriver() =0;
552 * @brief Prepares and executes a binary query in one step, and discards
555 * This function is not thread safe and must be included in any locks.
557 * @param query Query string.
558 * @param length Length of query string.
559 * @return True on success, false otherwise.
561 virtual bool DoSimpleQueryEx(const char *query, size_t len) =0;
564 * @brief Prepares and executes a binary query in one step, and returns
565 * the resultant data set.
567 * Note: If a query contains more than one result set, each
568 * result set must be processed before a new query is started.
570 * This function is not thread safe and must be included in any locks.
572 * @param query Query string.
573 * @return IQuery pointer on success, NULL otherwise.
575 virtual IQuery *DoQueryEx(const char *query, size_t len) =0;
578 * @brief Retrieves the number of affected rows from the last execute of
581 * Note: This can only accept queries from this driver.
583 * This function is not thread safe and must be included in any locks.
585 * @param query IQuery object from this driver
586 * @return Rows affected from last execution of this query,
589 virtual unsigned int GetAffectedRowsForQuery(IQuery *query) =0;
592 * @brief Retrieves the last insert id of the given query
594 * Note: This can only accept queries from this driver.
596 * This function is not thread safe and must be included in any locks.
598 * @param query IQuery object from this driver
599 * @return Insert Id from the last execution of this query,
602 virtual unsigned int GetInsertIDForQuery(IQuery *query) =0;
606 * @brief Describes database connection info.
612 dbiVersion = SMINTERFACE_DBI_VERSION;
616 unsigned int dbiVersion; /**< DBI Version for backwards compatibility */
617 const char *host; /**< Host string */
618 const char *database; /**< Database name string */
619 const char *user; /**< User to authenticate as */
620 const char *pass; /**< Password to authenticate with */
621 const char *driver; /**< Driver to use */
622 unsigned int port; /**< Port to use, 0=default */
623 unsigned int maxTimeout; /**< Maximum timeout, 0=default */
627 * @brief Describes an SQL driver.
632 virtual unsigned int GetDBIVersion()
634 return SMINTERFACE_DBI_VERSION;
638 * @brief Initiates a database connection.
640 * Note: Persistent connections should never be created from a thread.
642 * @param info Database connection info pointer.
643 * @param persistent If true, a previous persistent connection will
644 * be re-used if possible.
645 * @param error Buffer to store error message.
646 * @param maxlength Maximum size of the error buffer.
647 * @return A new IDatabase pointer, or NULL on failure.
649 virtual IDatabase *Connect(const DatabaseInfo *info, bool persistent, char *error, size_t maxlength) =0;
652 * @brief Returns a case insensitive database identifier string.
654 * @return String containing an identifier.
656 virtual const char *GetIdentifier() =0;
659 * @brief Returns a case sensitive implementation name.
661 * @return String containing an implementation name.
663 virtual const char *GetProductName() =0;
666 * @brief Retrieves a Handle_t handle of the IDBDriver type.
668 * @return A Handle_t handle.
670 virtual Handle_t GetHandle() =0;
673 * @brief Returns the driver's controlling identity (must be the same
674 * as from IExtension::GetIdentity).
676 * @return An IdentityToken_t identity.
678 virtual IdentityToken_t *GetIdentity() =0;
681 * @brief Returns whether the driver is thread safe.
683 * @return True if thread safe, false otherwise.
685 virtual bool IsThreadSafe() =0;
688 * @brief Initializes thread safety for the calling thread.
690 * @return True on success, false otherwise.
692 virtual bool InitializeThreadSafety() =0;
695 * @brief Shuts down thread safety for the calling thread.
697 virtual void ShutdownThreadSafety() =0;
701 * @brief Priority queue level.
705 PrioQueue_High, /**< High priority */
706 PrioQueue_Normal, /**< Normal priority */
707 PrioQueue_Low /**< Low priority */
711 * Specification for a threaded database operation.
713 class IDBThreadOperation
717 * @brief Must return the driver this operation is using, or
718 * NULL if not using any driver. This is not never inside
721 * @return IDBDriver pointer.
723 virtual IDBDriver *GetDriver() =0;
726 * @brief Must return the object owning this threaded operation.
727 * This is never called inside the thread.
729 * @return IdentityToken_t pointer.
731 virtual IdentityToken_t *GetOwner() =0;
734 * @brief Called inside the thread; this is where any blocking
735 * or threaded operations must occur.
737 virtual void RunThreadPart() =0;
740 * @brief Called in a server frame after the thread operation
741 * has completed. This is the non-threaded completion callback,
742 * which although optional, is useful for pumping results back
743 * to normal game API.
745 virtual void RunThinkPart() =0;
748 * @brief If RunThinkPart() is not called, this will be called
749 * instead. Note that RunThreadPart() is ALWAYS called regardless,
750 * and this is only called when Core requests that the operation
751 * be scrapped (for example, the database driver might be unloading).
753 virtual void CancelThinkPart() =0;
756 * @brief Called when the operation is finalized and any resources
759 virtual void Destroy() =0;
763 * @brief Database-related Handle types.
767 DBHandle_Driver = 0, /**< Driver Handle */
768 DBHandle_Database = 1, /**< Database Handle */
772 * @brief Describes the DBI manager.
774 class IDBManager : public SMInterface
777 virtual const char *GetInterfaceName() =0;
778 virtual unsigned int GetInterfaceVersion() =0;
781 * @brief Adds a driver to the DBI system. Not thread safe.
783 * @param pDriver Database driver.
785 virtual void AddDriver(IDBDriver *pDriver) =0;
788 * @brief Removes a driver from the DBI system. Not thread safe.
790 * @param pDriver Database driver.
792 virtual void RemoveDriver(IDBDriver *pDriver) =0;
795 * @brief Searches for database info by name. Both the return pointer
796 * and all pointers contained therein should be considered volatile.
798 * @param name Named database info.
799 * @return DatabaseInfo pointer.
801 virtual const DatabaseInfo *FindDatabaseConf(const char *name) =0;
804 * @brief Tries to connect to a named database. Not thread safe.
806 * @param name Named database info.
807 * @param pdr Pointer to store the IDBDriver pointer in.
808 * If driver is not found, NULL will be stored.
809 * @param pdb Pointer to store the IDatabase pointer in.
810 * If connection fails, NULL will be stored.
811 * @param persistent If true, the dbmanager will attempt to PConnect
812 * instead of connect.
813 * @param error Error buffer to store a driver's error message.
814 * @param maxlength Maximum length of the error buffer.
815 * @return True on success, false otherwise.
817 virtual bool Connect(const char *name,
822 size_t maxlength) =0;
825 * @brief Returns the number of drivers loaded. Not thread safe.
827 * @return Number of drivers loaded.
829 virtual unsigned int GetDriverCount() =0;
832 * @brief Returns a driver by index. Not thread safe.
834 * @param index Driver index, starting from 0.
835 * @return IDBDriver pointer for the given index.
837 virtual IDBDriver *GetDriver(unsigned int index) =0;
840 * @brief Creates a Handle_t of the IDBDriver type. Not thread safe.
842 * @param type A DBHandleType value.
843 * @param ptr A pointer corrresponding to a DBHandleType
845 * @param pToken Identity pointer of the owning identity.
846 * @return A new Handle_t handle, or 0 on failure.
848 virtual Handle_t CreateHandle(DBHandleType type, void *ptr, IdentityToken_t *pToken) =0;
851 * @brief Reads an IDBDriver pointer from an IDBDriver handle. Not
854 * @param hndl Handle_t handle to read.
855 * @param type A DBHandleType value.
856 * @param ptr Pointer to store the object pointer.
857 * @return HandleError value.
859 virtual HandleError ReadHandle(Handle_t hndl, DBHandleType type, void **ptr) =0;
862 * @brief Releases an IDBDriver handle.
864 * @param hndl Handle_t handle to release.
865 * @param type A DBHandleType value.
866 * @param token Identity pointer of the owning identity.
867 * @return HandleError value.
869 virtual HandleError ReleaseHandle(Handle_t hndl, DBHandleType type, IdentityToken_t *token) =0;
872 * @brief Given a driver name, attempts to find it. If it is not found, SourceMod
873 * will attempt to load it. This function is not thread safe.
875 * @param driver Driver identifier name.
876 * @return IDBDriver pointer on success, NULL otherwise.
878 virtual IDBDriver *FindOrLoadDriver(const char *driver) =0;
881 * @brief Returns the default driver, or NULL if none is set. This
882 * function is not thread safe.
884 * @return IDBDriver pointer on success, NULL otherwise.
886 virtual IDBDriver *GetDefaultDriver() =0;
889 * @brief Adds a threaded database operation to the priority queue.
890 * This function is not thread safe.
892 * @param op Instance of an IDBThreadOperation.
893 * @param prio Priority level to run at.
894 * @return True on success, false on failure.
896 virtual bool AddToThreadQueue(IDBThreadOperation *op, PrioQueueLevel prio) =0;
899 * @brief Adds a dependency from one extension to the owner of a driver.
901 * @param myself Extension that is using the IDBDriver.
902 * @param driver Driver that is being used.
904 virtual void AddDependency(IExtension *myself, IDBDriver *driver) =0;
908 #endif //_INCLUDE_SOURCEMOD_INTERFACE_DBDRIVER_H_