Refactored database handles so that there are multiple instead of a single one.

This commit is contained in:
shavit 2019-05-31 17:32:03 +03:00
parent 0650d20eff
commit fd121092c8
9 changed files with 132 additions and 420 deletions

View File

@ -267,6 +267,38 @@ char gS_CSGOColors[][] =
};
#endif
// connects synchronously to the bhoptimer database
// calls errors if needed
stock Database GetTimerDatabaseHandle()
{
Database db = null;
char sError[255];
if(SQL_CheckConfig("shavit"))
{
if((db = SQL_Connect("shavit", true, sError, 255)) == null)
{
SetFailState("Timer startup failed. Reason: %s", sError);
}
}
else
{
db = SQLite_UseDatabase("shavit", sError, 255);
}
return db
}
// figures out if the database is a mysql database
stock bool IsMySQLDatabase(Database db)
{
char sDriver[8];
db.Driver.GetIdentifier(sDriver, 8);
return StrEqual(sDriver, "mysql", false);
}
// retrieves the table prefix defined in configs/shavit-prefix.txt
stock void GetTimerSQLPrefix(char[] buffer, int maxlen)
{
@ -564,7 +596,8 @@ forward void Shavit_OnStyleChanged(int client, int oldstyle, int newstyle, int t
forward void Shavit_OnStyleConfigLoaded(int styles);
/**
* Called when there's a successful connection to the database.
* Called when there's a successful connection to the database and it is ready to be used.
* Called through shavit-core after migrations have been applied, and after the attempt to create the default `users` table.
*
* @noreturn
*/

View File

@ -112,16 +112,6 @@ public Plugin myinfo =
url = "https://github.com/shavitush/bhoptimer"
}
public void OnAllPluginsLoaded()
{
gB_RTLer = LibraryExists("rtler");
if(gH_SQL == null)
{
Shavit_OnDatabaseLoaded();
}
}
public void OnPluginStart()
{
gEV_Type = GetEngineVersion();
@ -163,6 +153,10 @@ public void OnPluginStart()
}
}
}
gB_RTLer = LibraryExists("rtler");
SQL_DBConnect();
}
public void OnMapStart()
@ -514,36 +508,6 @@ void Frame_SendText(DataPack pack)
EndMessage();
}
public void Shavit_OnDatabaseLoaded()
{
gH_SQL = Shavit_GetDatabase();
SetSQLInfo();
}
public Action CheckForSQLInfo(Handle Timer)
{
return SetSQLInfo();
}
Action SetSQLInfo()
{
if(gH_SQL == null)
{
gH_SQL = Shavit_GetDatabase();
CreateTimer(0.5, CheckForSQLInfo);
}
else
{
SQL_DBConnect();
return Plugin_Stop;
}
return Plugin_Continue;
}
public void OnLibraryAdded(const char[] name)
{
if(StrEqual(name, "rtler"))
@ -606,10 +570,7 @@ public void OnClientDisconnect(int client)
public void OnClientPostAdminCheck(int client)
{
if(gH_SQL != null)
{
LoadFromDatabase(client);
}
}
public Action Command_CCHelp(int client, int args)
@ -1307,16 +1268,11 @@ int RealRandomInt(int min, int max)
void SQL_DBConnect()
{
GetTimerSQLPrefix(gS_MySQLPrefix, 32);
if(gH_SQL != null)
{
char sDriver[8];
gH_SQL.Driver.GetIdentifier(sDriver, 8);
bool bMySQL = StrEqual(sDriver, "mysql", false);
gH_SQL = GetTimerDatabaseHandle();
char sQuery[512];
if(bMySQL)
if(IsMySQLDatabase(gH_SQL))
{
FormatEx(sQuery, 512,
"CREATE TABLE IF NOT EXISTS `%schat` (`auth` INT NOT NULL, `name` INT NOT NULL DEFAULT 0, `ccname` VARCHAR(128) COLLATE 'utf8mb4_unicode_ci', `message` INT NOT NULL DEFAULT 0, `ccmessage` VARCHAR(16) COLLATE 'utf8mb4_unicode_ci', PRIMARY KEY (`auth`), CONSTRAINT `%sch_auth` FOREIGN KEY (`auth`) REFERENCES `%susers` (`auth`) ON UPDATE CASCADE ON DELETE CASCADE) ENGINE=INNODB;",
@ -1331,7 +1287,6 @@ void SQL_DBConnect()
}
gH_SQL.Query(SQL_CreateTable_Callback, sQuery);
}
}
public void SQL_CreateTable_Callback(Database db, DBResultSet results, const char[] error, any data)

View File

@ -253,9 +253,6 @@ public void OnPluginStart()
SetFailState("This plugin was meant to be used in CS:S, CS:GO and TF2 *only*.");
}
// database connections
SQL_DBConnect();
// hooks
gB_HookedJump = HookEventEx("player_jump", Player_Jump);
HookEvent("player_death", Player_Death);
@ -360,6 +357,9 @@ public void OnPluginStart()
gB_Replay = LibraryExists("shavit-replay");
gB_Rankings = LibraryExists("shavit-rankings");
gB_HUD = LibraryExists("shavit-hud");
// database connections
SQL_DBConnect();
}
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
@ -1870,11 +1870,6 @@ public void OnClientPutInServer(int client)
CallOnStyleChanged(client, 0, gI_DefaultStyle, false);
}
if(gH_SQL == null)
{
return;
}
SDKHook(client, SDKHook_PreThinkPost, PreThinkPost);
int iSteamID = GetSteamAccountID(client);
@ -2161,28 +2156,8 @@ bool LoadMessages()
void SQL_DBConnect()
{
GetTimerSQLPrefix(gS_MySQLPrefix, 32);
if(gH_SQL != null)
{
delete gH_SQL;
}
char sError[255];
if(SQL_CheckConfig("shavit")) // can't be asynced as we have modules that require this database connection instantly
{
gH_SQL = SQL_Connect("shavit", true, sError, 255);
if(gH_SQL == null)
{
SetFailState("Timer startup failed. Reason: %s", sError);
}
}
else
{
gH_SQL = SQLite_UseDatabase("shavit", sError, 255);
}
gH_SQL = GetTimerDatabaseHandle();
gB_MySQL = IsMySQLDatabase(gH_SQL);
// support unicode names
if(!gH_SQL.SetCharset("utf8mb4"))
@ -2190,10 +2165,6 @@ void SQL_DBConnect()
gH_SQL.SetCharset("utf8");
}
char sDriver[8];
gH_SQL.Driver.GetIdentifier(sDriver, 8);
gB_MySQL = StrEqual(sDriver, "mysql", false);
// migrations will only exist for mysql. sorry sqlite users
if(gB_MySQL)
{

View File

@ -120,16 +120,6 @@ public void OnAllPluginsLoaded()
{
SetFailState("shavit-wr is required for the plugin to work.");
}
if(gH_SQL == null)
{
Shavit_OnDatabaseLoaded();
}
for(int i = 0; i < TRACKS_SIZE; i++)
{
GetTrackName(LANG_SERVER, i, gS_TrackNames[i], 32);
}
}
public void OnPluginStart()
@ -141,7 +131,7 @@ public void OnPluginStart()
RegConsoleCmd("sm_maptier", Command_Tier, "Prints the map's tier to chat. (sm_tier alias)");
RegConsoleCmd("sm_rank", Command_Rank, "Show your or someone else's rank. Usage: sm_rank [name]");
RegConsoleCmd("sm_top", Command_Top, "Show the top 100 players."); // The rewrite of rankings will not have the ability to show over 100 entries. Dynamic fetching can be exploited and overload the database.
RegConsoleCmd("sm_top", Command_Top, "Show the top 100 players.");
RegAdminCmd("sm_settier", Command_SetTier, ADMFLAG_RCON, "Change the map's tier. Usage: sm_settier <tier>");
RegAdminCmd("sm_setmaptier", Command_SetTier, ADMFLAG_RCON, "Change the map's tier. Usage: sm_setmaptier <tier> (sm_settier alias)");
@ -168,6 +158,13 @@ public void OnPluginStart()
{
Shavit_OnChatConfigLoaded();
}
for(int i = 0; i < TRACKS_SIZE; i++)
{
GetTrackName(LANG_SERVER, i, gS_TrackNames[i], 32);
}
SQL_DBConnect();
}
public void Shavit_OnChatConfigLoaded()
@ -210,46 +207,12 @@ public void OnLibraryRemoved(const char[] name)
}
}
public void Shavit_OnDatabaseLoaded()
{
gH_SQL = Shavit_GetDatabase();
SetSQLInfo();
}
public Action CheckForSQLInfo(Handle Timer)
{
return SetSQLInfo();
}
Action SetSQLInfo()
{
if(gH_SQL == null)
{
gH_SQL = Shavit_GetDatabase();
CreateTimer(0.5, CheckForSQLInfo);
}
else
{
SQL_DBConnect();
return Plugin_Stop;
}
return Plugin_Continue;
}
void SQL_DBConnect()
{
GetTimerSQLPrefix(gS_MySQLPrefix, 32);
gH_SQL = GetTimerDatabaseHandle();
if(gH_SQL != null)
{
char sDriver[8];
gH_SQL.Driver.GetIdentifier(sDriver, 8);
if(!StrEqual(sDriver, "mysql", false))
if(!IsMySQLDatabase(gH_SQL))
{
SetFailState("MySQL is the only supported database engine for shavit-rankings.");
}
@ -258,7 +221,6 @@ void SQL_DBConnect()
FormatEx(sQuery, 256, "CREATE TABLE IF NOT EXISTS `%smaptiers` (`map` VARCHAR(128), `tier` INT NOT NULL DEFAULT 1, PRIMARY KEY (`map`)) ENGINE=INNODB;", gS_MySQLPrefix);
gH_SQL.Query(SQL_CreateTable_Callback, sQuery, 0);
}
}
public void SQL_CreateTable_Callback(Database db, DBResultSet results, const char[] error, any data)
@ -379,7 +341,7 @@ public void OnClientPostAdminCheck(int client)
public void OnMapStart()
{
// do NOT keep running this more than once per map, as UpdateAllPoints() is called after this eventually and locks up the database while it is running
if(gH_SQL == null || gB_TierQueried)
if(gB_TierQueried)
{
return;
}

View File

@ -210,11 +210,6 @@ public void OnAllPluginsLoaded()
{
SetFailState("shavit-wr is required for the plugin to work.");
}
if(gH_SQL == null)
{
Shavit_OnDatabaseLoaded();
}
}
public void OnPluginStart()
@ -297,6 +292,10 @@ public void OnPluginStart()
// commands
RegAdminCmd("sm_deletereplay", Command_DeleteReplay, ADMFLAG_RCON, "Open replay deletion menu.");
RegConsoleCmd("sm_replay", Command_Replay, "Opens the central bot menu. For admins: 'sm_replay stop' to stop the playback.");
// database
GetTimerSQLPrefix(gS_MySQLPrefix, 32);
gH_SQL = GetTimerDatabaseHandle();
}
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
@ -686,36 +685,6 @@ public int Native_Replay_DeleteMap(Handle handler, int numParams)
}
}
public void Shavit_OnDatabaseLoaded()
{
gH_SQL = Shavit_GetDatabase();
SetSQLInfo();
}
public Action CheckForSQLInfo(Handle Timer)
{
return SetSQLInfo();
}
Action SetSQLInfo()
{
if(gH_SQL == null)
{
gH_SQL = Shavit_GetDatabase();
CreateTimer(0.5, CheckForSQLInfo);
}
else
{
GetTimerSQLPrefix(gS_MySQLPrefix, 32);
return Plugin_Stop;
}
return Plugin_Continue;
}
public Action Cron(Handle Timer)
{
if(!gCV_Enabled.BoolValue)
@ -1005,8 +974,6 @@ bool LoadCurrentReplayFormat(File file, int version, int style, int track)
iSteamID = StringToInt(sAuthID);
}
if(gH_SQL != null)
{
char sQuery[192];
FormatEx(sQuery, 192, "SELECT name FROM %susers WHERE auth = %d;", gS_MySQLPrefix, iSteamID);
@ -1015,7 +982,6 @@ bool LoadCurrentReplayFormat(File file, int version, int style, int track)
hPack.WriteCell(track);
gH_SQL.Query(SQL_GetUserName_Callback, sQuery, hPack, DBPrio_High);
}
int cells = CELLS_PER_FRAME;

View File

@ -39,12 +39,10 @@ bool gB_Rankings = false;
// database handle
Database gH_SQL = null;
// table prefix
char gS_MySQLPrefix[32];
// cache
bool gB_AllowStats[MAXPLAYERS+1];
bool gB_CanOpenMenu[MAXPLAYERS+1];
int gI_MapType[MAXPLAYERS+1];
int gI_Style[MAXPLAYERS+1];
int gI_Track[MAXPLAYERS+1];
@ -95,11 +93,6 @@ public void OnAllPluginsLoaded()
{
SetFailState("shavit-wr is required for the plugin to work.");
}
if(gH_SQL == null)
{
Shavit_OnDatabaseLoaded();
}
}
public void OnPluginStart()
@ -139,6 +132,10 @@ public void OnPluginStart()
}
}
}
// database
GetTimerSQLPrefix(gS_MySQLPrefix, 32);
gH_SQL = GetTimerDatabaseHandle();
}
public void OnMapStart()
@ -184,7 +181,7 @@ public void OnClientPutInServer(int client)
return;
}
gB_AllowStats[client] = true;
gB_CanOpenMenu[client] = true;
gI_WRAmount[client] = 0;
UpdateWRs(client);
}
@ -205,36 +202,6 @@ public void OnLibraryRemoved(const char[] name)
}
}
public void Shavit_OnDatabaseLoaded()
{
gH_SQL = Shavit_GetDatabase();
SetSQLInfo();
}
public Action CheckForSQLInfo(Handle Timer)
{
return SetSQLInfo();
}
Action SetSQLInfo()
{
if(gH_SQL == null)
{
gH_SQL = Shavit_GetDatabase();
CreateTimer(0.5, CheckForSQLInfo);
}
else
{
GetTimerSQLPrefix(gS_MySQLPrefix, 32);
return Plugin_Stop;
}
return Plugin_Continue;
}
public void Player_Event(Event event, const char[] name, bool dontBroadcast)
{
if(gCV_MVPRankOnes.IntValue == 0)
@ -252,11 +219,6 @@ public void Player_Event(Event event, const char[] name, bool dontBroadcast)
void UpdateWRs(int client)
{
if(gH_SQL == null)
{
return;
}
int iSteamID = 0;
if((iSteamID = GetSteamAccountID(client)) != 0)
@ -455,7 +417,7 @@ public Action Command_Profile(int client, int args)
Action OpenStatsMenu(int client, int steamid)
{
// no spam please
if(!gB_AllowStats[client])
if(!gB_CanOpenMenu[client])
{
return Plugin_Handled;
}
@ -484,7 +446,7 @@ Action OpenStatsMenu(int client, int steamid)
"LIMIT 1;", gS_MySQLPrefix, steamid, gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, steamid, gS_MySQLPrefix, steamid);
}
gB_AllowStats[client] = false;
gB_CanOpenMenu[client] = false;
gH_SQL.Query(OpenStatsMenuCallback, sQuery, GetClientSerial(client), DBPrio_Low);
return Plugin_Handled;
@ -493,7 +455,7 @@ Action OpenStatsMenu(int client, int steamid)
public void OpenStatsMenuCallback(Database db, DBResultSet results, const char[] error, any data)
{
int client = GetClientFromSerial(data);
gB_AllowStats[client] = true;
gB_CanOpenMenu[client] = true;
if(results == null)
{
@ -675,27 +637,10 @@ public int MenuHandler_TypeHandler(Menu menu, MenuAction action, int param1, int
return 0;
}
public Action Timer_DBFailure(Handle timer, any data)
{
int client = GetClientFromSerial(data);
if(client == 0)
{
return Plugin_Stop;
}
ShowMaps(client);
return Plugin_Stop;
}
void ShowMaps(int client)
{
// database not found, display with a 3 seconds delay
if(gH_SQL == null)
if(!gB_CanOpenMenu[client])
{
CreateTimer(3.0, Timer_DBFailure, GetClientSerial(client));
return;
}
@ -725,6 +670,8 @@ void ShowMaps(int client)
}
}
gB_CanOpenMenu[client] = false;
gH_SQL.Query(ShowMapsCallback, sQuery, GetClientSerial(client), DBPrio_High);
}
@ -744,6 +691,8 @@ public void ShowMapsCallback(Database db, DBResultSet results, const char[] erro
return;
}
gB_CanOpenMenu[client] = true;
int rows = results.RowCount;
char sTrack[32];

View File

@ -74,11 +74,6 @@ public void OnAllPluginsLoaded()
{
SetFailState("shavit-wr is required for the plugin to work.");
}
if(gH_SQL == null)
{
Shavit_OnDatabaseLoaded();
}
}
public void OnPluginStart()
@ -109,6 +104,9 @@ public void OnPluginStart()
gCV_ForceMapEnd.AddChangeHook(OnConVarChanged);
AutoExecConfig();
GetTimerSQLPrefix(gS_MySQLPrefix, 32);
gH_SQL = GetTimerDatabaseHandle();
}
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
@ -147,11 +145,6 @@ public void OnConfigsExecuted()
public void OnMapStart()
{
if(gH_SQL == null)
{
return;
}
if(gCV_DynamicTimelimits.BoolValue)
{
StartCalculating();
@ -168,41 +161,8 @@ public void OnMapStart()
}
}
public void Shavit_OnDatabaseLoaded()
{
gH_SQL = Shavit_GetDatabase();
SetSQLInfo();
}
public Action CheckForSQLInfo(Handle Timer)
{
return SetSQLInfo();
}
Action SetSQLInfo()
{
if(gH_SQL == null)
{
gH_SQL = Shavit_GetDatabase();
CreateTimer(0.5, CheckForSQLInfo);
}
else
{
GetTimerSQLPrefix(gS_MySQLPrefix, 32);
OnMapStart();
return Plugin_Stop;
}
return Plugin_Continue;
}
void StartCalculating()
{
if(gH_SQL != null)
{
char sMap[160];
GetCurrentMap(sMap, 160);
GetMapDisplayName(sMap, sMap, 160);
@ -215,7 +175,6 @@ void StartCalculating()
#endif
gH_SQL.Query(SQL_GetMapTimes, sQuery, 0, DBPrio_Low);
}
}
public void SQL_GetMapTimes(Database db, DBResultSet results, const char[] error, any data)

View File

@ -117,14 +117,6 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
return APLRes_Success;
}
public void OnAllPluginsLoaded()
{
if(gH_SQL == null)
{
Shavit_OnDatabaseLoaded();
}
}
public void OnPluginStart()
{
LoadTranslations("shavit-common.phrases");
@ -177,6 +169,9 @@ public void OnPluginStart()
// cache
gA_ValidMaps = new ArrayList(192);
// database
SQL_DBConnect();
}
public void OnAdminMenuCreated(Handle topmenu)
@ -280,7 +275,7 @@ public void OnLibraryRemoved(const char[] name)
public void OnMapStart()
{
if(gH_SQL == null || !gB_Connected)
if(!gB_Connected)
{
return;
}
@ -412,7 +407,7 @@ public void OnClientPutInServer(int client)
}
}
if(!IsClientConnected(client) || IsFakeClient(client) || gH_SQL == null)
if(!IsClientConnected(client) || IsFakeClient(client))
{
return;
}
@ -1882,43 +1877,11 @@ public int SubMenu_Handler(Menu menu, MenuAction action, int param1, int param2)
return 0;
}
public void Shavit_OnDatabaseLoaded()
{
gH_SQL = Shavit_GetDatabase();
SetSQLInfo();
}
public Action CheckForSQLInfo(Handle Timer)
{
return SetSQLInfo();
}
Action SetSQLInfo()
{
if(gH_SQL == null)
{
gH_SQL = Shavit_GetDatabase();
CreateTimer(0.5, CheckForSQLInfo);
}
else
{
SQL_DBConnect();
return Plugin_Stop;
}
return Plugin_Continue;
}
void SQL_DBConnect()
{
GetTimerSQLPrefix(gS_MySQLPrefix, 32);
char sDriver[8];
gH_SQL.Driver.GetIdentifier(sDriver, 8);
gB_MySQL = StrEqual(sDriver, "mysql", false);
gH_SQL = GetTimerDatabaseHandle();
gB_MySQL = IsMySQLDatabase(gH_SQL);
char sQuery[1024];
@ -2056,11 +2019,6 @@ public void Shavit_OnFinish(int client, int style, float time, int jumps, int st
{
Shavit_PrintToChatAll("%s[%s]%s %T", gS_ChatStrings.sVariable, sTrack, gS_ChatStrings.sText, "FirstCompletion", LANG_SERVER, gS_ChatStrings.sVariable2, client, gS_ChatStrings.sText, gS_ChatStrings.sStyle, gS_StyleStrings[style].sStyleName, gS_ChatStrings.sText, gS_ChatStrings.sVariable2, sTime, gS_ChatStrings.sText, gS_ChatStrings.sVariable, iRank, gS_ChatStrings.sText, jumps, strafes, sSync, gS_ChatStrings.sText);
if(gH_SQL == null)
{
return;
}
FormatEx(sQuery, 512,
"INSERT INTO %splayertimes (auth, map, time, jumps, date, style, strafes, sync, points, track, perfs) VALUES (%d, '%s', %f, %d, %d, %d, %d, %.2f, 0.0, %d, %.2f);",
gS_MySQLPrefix, iSteamID, gS_Map, time, jumps, GetTime(), style, strafes, sync, track, perfs);

View File

@ -191,14 +191,6 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
return APLRes_Success;
}
public void OnAllPluginsLoaded()
{
if(gH_SQL == null)
{
Shavit_OnDatabaseLoaded();
}
}
public void OnPluginStart()
{
LoadTranslations("shavit-common.phrases");
@ -287,6 +279,8 @@ public void OnPluginStart()
OnClientPutInServer(i);
}
}
SQL_DBConnect();
}
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
@ -624,7 +618,7 @@ void LoadZoneSettings()
public void OnMapStart()
{
if(gH_SQL == null || !gB_Connected)
if(!gB_Connected)
{
return;
}
@ -2500,45 +2494,11 @@ void CreateZonePoints(float point[8][3], float offset = 0.0)
}
}
public void Shavit_OnDatabaseLoaded()
{
gH_SQL = Shavit_GetDatabase();
SetSQLInfo();
}
public Action CheckForSQLInfo(Handle Timer)
{
return SetSQLInfo();
}
Action SetSQLInfo()
{
if(gH_SQL == null)
{
gH_SQL = Shavit_GetDatabase();
CreateTimer(0.5, CheckForSQLInfo);
}
else
{
SQL_DBConnect();
return Plugin_Stop;
}
return Plugin_Continue;
}
void SQL_DBConnect()
{
GetTimerSQLPrefix(gS_MySQLPrefix, 32);
if(gH_SQL != null)
{
char sDriver[8];
gH_SQL.Driver.GetIdentifier(sDriver, 8);
gB_MySQL = StrEqual(sDriver, "mysql", false);
gH_SQL = GetTimerDatabaseHandle();
gB_MySQL = IsMySQLDatabase(gH_SQL);
char sQuery[1024];
FormatEx(sQuery, 1024,
@ -2546,7 +2506,6 @@ void SQL_DBConnect()
gS_MySQLPrefix, (gB_MySQL)? " ENGINE=INNODB":"");
gH_SQL.Query(SQL_CreateTable_Callback, sQuery);
}
}
public void SQL_CreateTable_Callback(Database db, DBResultSet results, const char[] error, any data)