diff --git a/core/smn_database.cpp b/core/smn_database.cpp index bb156147..5f6c3a97 100644 --- a/core/smn_database.cpp +++ b/core/smn_database.cpp @@ -1407,6 +1407,23 @@ static cell_t SQL_ConnectCustom(IPluginContext *pContext, const cell_t *params) return hndl; } +static cell_t SQL_SetCharset(IPluginContext *pContext, const cell_t *params) +{ + IDatabase *db = NULL; + HandleError err; + + if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err); + } + + char *characterset; + pContext->LocalToString(params[2], &characterset); + + return db->SetCharacterSet(characterset); +} + REGISTER_NATIVES(dbNatives) { {"SQL_BindParamInt", SQL_BindParamInt}, @@ -1448,6 +1465,7 @@ REGISTER_NATIVES(dbNatives) {"SQL_TQuery", SQL_TQuery}, {"SQL_UnlockDatabase", SQL_UnlockDatabase}, {"SQL_ConnectCustom", SQL_ConnectCustom}, + {"SQL_SetCharset", SQL_SetCharset}, {NULL, NULL}, }; diff --git a/extensions/mysql/mysql/MyDatabase.cpp b/extensions/mysql/mysql/MyDatabase.cpp index e62ccbfd..9b338ed1 100644 --- a/extensions/mysql/mysql/MyDatabase.cpp +++ b/extensions/mysql/mysql/MyDatabase.cpp @@ -326,3 +326,8 @@ IDBDriver *MyDatabase::GetDriver() { return &g_MyDriver; } + +bool MyDatabase::SetCharacterSet(const char *characterset) +{ + return mysql_set_character_set(m_mysql, characterset) == 0 ? true : false; +} \ No newline at end of file diff --git a/extensions/mysql/mysql/MyDatabase.h b/extensions/mysql/mysql/MyDatabase.h index 12420ab2..50594b6e 100644 --- a/extensions/mysql/mysql/MyDatabase.h +++ b/extensions/mysql/mysql/MyDatabase.h @@ -62,6 +62,7 @@ public: //IDatabase IQuery *DoQueryEx(const char *query, size_t len); unsigned int GetAffectedRowsForQuery(IQuery *query); unsigned int GetInsertIDForQuery(IQuery *query); + bool SetCharacterSet(const char *characterset); public: const DatabaseInfo &GetInfo(); private: diff --git a/extensions/sqlite/driver/SqDatabase.cpp b/extensions/sqlite/driver/SqDatabase.cpp index dfe0325f..7686edda 100644 --- a/extensions/sqlite/driver/SqDatabase.cpp +++ b/extensions/sqlite/driver/SqDatabase.cpp @@ -254,3 +254,9 @@ sqlite3 *SqDatabase::GetDb() { return m_sq3; } + +bool SqDatabase::SetCharacterSet(const char *characterset) +{ + // sqlite only supports utf8 and utf16 - by the time the database is created. It's too late here. + return false; +} \ No newline at end of file diff --git a/extensions/sqlite/driver/SqDatabase.h b/extensions/sqlite/driver/SqDatabase.h index ec016077..72b2405c 100644 --- a/extensions/sqlite/driver/SqDatabase.h +++ b/extensions/sqlite/driver/SqDatabase.h @@ -58,6 +58,7 @@ public: IQuery *DoQueryEx(const char *query, size_t len); unsigned int GetAffectedRowsForQuery(IQuery *query); unsigned int GetInsertIDForQuery(IQuery *query); + bool SetCharacterSet(const char *characterset); public: sqlite3 *GetDb(); private: diff --git a/plugins/include/dbi.inc b/plugins/include/dbi.inc index 71a784bd..4cb12e2c 100644 --- a/plugins/include/dbi.inc +++ b/plugins/include/dbi.inc @@ -249,6 +249,18 @@ native SQL_GetDriverIdent(Handle:driver, String:ident[], maxlength); */ native SQL_GetDriverProduct(Handle:driver, String:product[], maxlength); +/** + * Sets the character set of the current connection. + * Like SET NAMES .. in mysql, but stays after connection problems. + * + * Example: "utf8", "latin1" + * + * @param database Database Handle. + * @param characterset The character set string to change to. + * @return True, if character set was changed, false otherwise. + */ +native bool:SQL_SetCharset(Handle:database, const String:charset[]); + /** * Returns the number of affected rows from the last query. * diff --git a/public/IDBDriver.h b/public/IDBDriver.h index adad660a..7d13e148 100644 --- a/public/IDBDriver.h +++ b/public/IDBDriver.h @@ -42,7 +42,7 @@ */ #define SMINTERFACE_DBI_NAME "IDBI" -#define SMINTERFACE_DBI_VERSION 8 +#define SMINTERFACE_DBI_VERSION 9 namespace SourceMod { @@ -600,6 +600,13 @@ namespace SourceMod * if applicable. */ virtual unsigned int GetInsertIDForQuery(IQuery *query) =0; + + /** + * @brief Sets the character set of the current connection + * + * @param characterset The characterset to switch to. e.g. "utf8". + */ + virtual bool SetCharacterSet(const char *characterset) =0; }; /**