ISource2ModSQL

Interfaces and utilities for SQL database access: MySQL and SQLite behind one interface.

This module provides functionality for:

  • MySQL and SQLite connections (ESource2ModSQLDriver), or ones named in configs/databases.json
  • Query execution
  • Transactions
  • Result set handling
  • Data escaping
Commonly used for persistent storage and asynchronous database operations.

Interface id ISource2ModSQL001 (SOURCE2MOD_SQL_INTERFACE) · Global g_pSource2ModSQL · Header source2mod/ISource2ModSQL.h

Types

Source2ModSQLConnectCallbackFunc

typedef std::function<void(bool)> Source2ModSQLConnectCallbackFunc;

Source2ModSQLQueryCallbackFunc

typedef std::function<void(ISource2ModSQLQuery*)> Source2ModSQLQueryCallbackFunc;

Source2ModSQLTransactionSuccessCallbackFunc

typedef std::function<void(std::vector<ISource2ModSQLQuery*>)> Source2ModSQLTransactionSuccessCallbackFunc;

Source2ModSQLTransactionFailureCallbackFunc

typedef std::function<void(std::string, int)> Source2ModSQLTransactionFailureCallbackFunc;

Source2ModSQLServerlessCallbackFunc

typedef std::function<void(const Source2ModSQLServerlessResult&)> Source2ModSQLServerlessCallbackFunc;

Callback for a completed serverless query. Runs on the main thread.

Methods

CreateConnection

virtual ISource2ModSQLConnection* CreateConnection(PluginId owner, Source2ModSQLConnectionInfo info) = 0;

Creates a new connection instance (MySQL or SQLite, by info.driver).

Destroyed for you if the owning plugin unloads without calling Destroy(): the worker thread runs code, and the query callbacks are std::functions holding code, inside that plugin's library.
ParameterTypeDescription
ownerPluginIdPlugin the connection belongs to.
infoSource2ModSQLConnectionInfoConnection configuration data.

Returns ISource2ModSQLConnection* — Newly created connection.

CreateServerless

virtual ISource2ModSQLServerless* CreateServerless(PluginId owner, Source2ModSQLConnectionInfo info) = 0;

Creates a handle that runs each of its queries on a connection of its own, opened and closed around that one query.

Destroyed for you if the owning plugin unloads without calling Destroy(), together with every query of its still in the air: a pending callback is a std::function holding code inside that plugin's library.
ParameterTypeDescription
ownerPluginIdPlugin the handle belongs to.
infoSource2ModSQLConnectionInfoConnection configuration data. Copied, strings included -- it does not have to outlive this call.

Returns ISource2ModSQLServerless* — Newly created serverless handle.

GetNamedConnection

virtual bool GetNamedConnection(const char* name, Source2ModSQLConnectionInfo& info) = 0;

The connection details named @p name in configs/databases.json ({"name": {"driver": "mysql"|"sqlite", "host", "user", "pass", "database", "port", "timeout"}}), or "default" for an empty name.

ParameterTypeDescription
nameconst char*
infoSource2ModSQLConnectionInfo&Filled in when found; its strings stay valid until the config is read again (map change).

Returns bool — false when there is no such entry.

Source2ModSQLTransaction

Fields

FieldType
queriesstd::vector<std::string>

Source2ModSQLConnectionInfo

Fields

FieldTypeDescription
hostconst char*
userconst char*
passconst char*
databaseconst char*
portint
timeoutint
driverESource2ModSQLDriverWhich server this is; MySQL unless said otherwise.

ISource2ModSQLRow

ISource2ModSQLResult

GetRowCount

virtual int GetRowCount() = 0;

Returns the total number of rows in the result set.

GetFieldCount

virtual int GetFieldCount() = 0;

Returns the number of columns in the result set.

FieldNameToNum

virtual bool FieldNameToNum(const char* name, unsigned int* columnId) = 0;

Converts a field name into a column index.

ParameterTypeDescription
nameconst char*Field name to search for.
columnIdunsigned int*Output column index.

Returns bool — True if the field exists, false otherwise.

FieldNumToName

virtual const char* FieldNumToName(unsigned int colId) = 0;

Returns the field name for a column index.

ParameterTypeDescription
colIdunsigned intColumn index.

Returns const char* — Field name string.

MoreRows

virtual bool MoreRows() = 0;

Checks whether additional rows are available.

Returns bool — True if more rows can be fetched.

FetchRow

virtual ISource2ModSQLRow* FetchRow() = 0;

Fetches the next row from the result set.

Returns ISource2ModSQLRow* — Pointer to the fetched row.

CurrentRow

virtual ISource2ModSQLRow* CurrentRow() = 0;

Returns the currently active row.

Returns ISource2ModSQLRow* — Pointer to the current row.

Rewind

virtual bool Rewind() = 0;

Rewinds the internal row cursor to the beginning.

Returns bool — True on success.

GetFieldType

virtual int GetFieldType(unsigned int field) = 0;

Returns the field type of a column (ESource2ModSQLType numbering).

ParameterTypeDescription
fieldunsigned intColumn index.

Returns int — Field type identifier.

GetString

virtual const char* GetString(unsigned int columnId, size_t* length = nullptr) = 0;

Retrieves a string value from a column.

ParameterTypeDefaultDescription
columnIdunsigned intColumn index.
lengthsize_t*nullptrOptional output string length.

Returns const char* — Pointer to string data.

GetDataSize

virtual size_t GetDataSize(unsigned int columnId) = 0;

Returns the raw data size of a column value.

ParameterTypeDescription
columnIdunsigned intColumn index.

Returns size_t — Size in bytes.

GetFloat

virtual float GetFloat(unsigned int columnId) = 0;

Retrieves a floating-point value from a column.

ParameterTypeDescription
columnIdunsigned intColumn index.

Returns float — Float value.

GetInt

virtual int GetInt(unsigned int columnId) = 0;

Retrieves an integer value from a column.

ParameterTypeDescription
columnIdunsigned intColumn index.

Returns int — Integer value.

GetInt64

virtual int64_t GetInt64(unsigned int columnId) = 0;

Retrieves a 64-bit integer value from a column.

ParameterTypeDescription
columnIdunsigned intColumn index.

Returns int64_t — 64-bit integer value.

IsNull

virtual bool IsNull(unsigned int columnId) = 0;

Checks whether a column contains a NULL value.

ParameterTypeDescription
columnIdunsigned intColumn index.

Returns bool — True if the value is NULL.

ISource2ModSQLQuery

GetResultSet

virtual ISource2ModSQLResult* GetResultSet() = 0;

Returns the current result set.

Returns ISource2ModSQLResult* — Pointer to the result set.

FetchMoreResults

virtual bool FetchMoreResults() = 0;

Advances to the next available result set.

Returns bool — True if another result set exists.

GetInsertId

virtual unsigned int GetInsertId() = 0;

Returns the last inserted row ID.

Returns unsigned int — Insert ID value.

GetAffectedRows

virtual unsigned int GetAffectedRows() = 0;

Returns the number of affected rows.

Returns unsigned int — Affected row count.

ISource2ModSQLConnection

Connect

virtual void Connect(Source2ModSQLConnectCallbackFunc callback) = 0;

Establishes the connection (opens the file, for SQLite).

ParameterTypeDescription
callbackSource2ModSQLConnectCallbackFuncCallback invoked after connection attempt.

Query

virtual void Query(char* query, Source2ModSQLQueryCallbackFunc callback) = 0;
virtual void Query(const char* query, Source2ModSQLQueryCallbackFunc callback, ...) = 0;

Executes a raw SQL query.

The callback always runs, once. On success it gets the query, owned by Source2Mod and valid only for the duration of the callback -- copy anything you keep, do not delete it. On failure it gets nullptr: the connection is not up (Connect() has not reported true yet, or it failed) or the server rejected the query. The reason is written to the server log.

Executes a formatted SQL query.

Same callback contract as the overload above: nullptr on failure, otherwise a source2mod-owned query valid only during the callback.
ParameterTypeDescription
querychar*SQL query string.
callbackSource2ModSQLQueryCallbackFuncCallback invoked with query result, on the main thread.
queryconst char*SQL query string.
—...

ExecuteTransaction

virtual void ExecuteTransaction(Source2ModSQLTransaction txn, Source2ModSQLTransactionSuccessCallbackFunc success, Source2ModSQLTransactionFailureCallbackFunc failure) = 0;

Executes multiple queries as a transaction.

Exactly one of the two callbacks runs, on the main thread.

@p txn, in order. They are owned by Source2Mod and freed once the callback returns -- copy anything you keep, do not delete them.

ParameterTypeDescription
txnSource2ModSQLTransactionTransaction query batch.
successSource2ModSQLTransactionSuccessCallbackFuncCallback invoked on success, with one query per entry of
failureSource2ModSQLTransactionFailureCallbackFuncCallback invoked on failure, after the transaction has been rolled back, with the error and the index of the query that failed -- or -1 when it was not one of them (not connected, BEGIN or COMMIT failed).

Destroy

virtual void Destroy() = 0;

Destroys and releases the connection instance.

GetDriver

virtual ESource2ModSQLDriver GetDriver() = 0;

The driver this connection talks to.

Escape

virtual std::string Escape(char* string) = 0;
virtual std::string Escape(const char* string) = 0;

Escapes a mutable string for safe SQL usage.

Escapes a constant string for safe SQL usage.

ParameterTypeDescription
stringchar*Input string.
stringconst char*Input string.

Returns std::string — Escaped string.

Source2ModSQLServerlessResult

What one serverless query came back with.

m_bSuccess is about the query, not about rows -- a SELECT that matched nothing is a success with an empty result set. A query that failed has m_bSuccess false, m_sError filled in and m_pQuery null.

Fields

FieldTypeDescription
m_bSuccessbool
m_nErrorCodeunsigned intThe driver's own error number (MySQL's, or SQLite's result code), or 0 when the query never reached the database.
m_sErrorstd::string
m_pQueryISource2ModSQLQuery*Rows, insert id and affected rows, read off the connection before it was closed again. Owned by Source2Mod and valid only for the duration of the callback -- copy anything you keep. Null when the query failed.

ISource2ModSQLServerless

A set of connection details that queries are run against one at a time.

Every query opens its own connection, runs, reads its rows out and closes again -- there is nothing to keep alive, nothing to reconnect, and nothing that can go stale over a map change. None of it happens on the main thread: queries go through Source2Mod's shared SQL worker, one thread for all of them however many plugins are using it, and land back in a callback on the main thread.

Meant for the occasional query -- loading a player on connect, writing their stats on disconnect. A connection costs a handshake and a login every single time, so for anything that runs per tick or per shot, keep an ISource2ModSQLConnection open instead.

// once, when your plugin loads
m_pDb = api->SQL()->CreateServerless(g_PLID, { "127.0.0.1", "user", "pass", "db" });

// wherever you need it
m_pDb->Query("SELECT name, kills FROM players WHERE steamid = ?", { steamid },
    [](const Source2ModSQLServerlessResult& r)
{
    if (!r.m_bSuccess)
        return; // r.m_sError says what went wrong

    ISource2ModSQLResult* pSet = r.m_pQuery->GetResultSet();
    while (pSet && pSet->MoreRows() && pSet->FetchRow())
    {
        // pSet->GetString(0), pSet->GetInt(1) -- copy anything you keep.
    }
});

Query

virtual void Query(const char* query, Source2ModSQLServerlessCallbackFunc callback) = 0;
virtual void Query(const char* query, std::vector<std::string> params, Source2ModSQLServerlessCallbackFunc callback) = 0;

Runs one query on a connection of its own.

Runs one parameterised query on a connection of its own.

Placeholders are filled in on the worker against the live connection: ? becomes the escaped value in quotes, ?? becomes a quoted identifier -- a table or column name, which cannot be a ?. A ? inside a string literal is left alone, and a placeholder count that does not match @p params fails the query instead of running it.

ParameterTypeDescription
queryconst char*SQL to run.
callbackSource2ModSQLServerlessCallbackFuncCallback invoked with the result, on the main thread.
paramsstd::vector<std::string>Values for the placeholders, in order.

Destroy

virtual void Destroy() = 0;

Drops these details and cancels what they still have queued. A query already on the wire is left to finish and its result thrown away -- its callback does not run.

Enums

ESource2ModSQLDriver

enum ESource2ModSQLDriver
NameValueDescription
SOURCE2MOD_SQL_DRIVER_MYSQL0A MySQL / MariaDB server: host, user, pass, database, port.
SOURCE2MOD_SQL_DRIVER_SQLITE1An SQLite file: database is its path (a relative one is under addons/source2mod/data, made when missing); host, user and pass unused.

Macros

MacroExpands to
SQL_CREATE_CONNECTION(info)g_pSource2ModSQL->CreateConnection(g_PluginID, info)

On this page