make wrhrankmain stuff use VIEWs instead of temp tables

This commit is contained in:
rtldg 2021-08-16 21:18:27 +00:00
parent 2eb78a2a14
commit d4b61a474f
2 changed files with 64 additions and 74 deletions

View File

@ -1788,7 +1788,7 @@ native void Shavit_OpenStatsMenu(int client, int steamid);
* @param track Track to retrieve WRs from. -1 to use all tracks. All bonus tracks are combined. * @param track Track to retrieve WRs from. -1 to use all tracks. All bonus tracks are combined.
* @param style Style to retrieve WRs from. -1 to use all styles. * @param style Style to retrieve WRs from. -1 to use all styles.
* @param usecvars Whether to depend on the value of `shavit_stats_mvprankones` and `shavit_stats_mvprankones_maintrack`. * @param usecvars Whether to depend on the value of `shavit_stats_mvprankones` and `shavit_stats_mvprankones_maintrack`.
* @noreturn * @return The number of WRs.
*/ */
native int Shavit_GetWRCount(int client, int track = -1, int style = -1, bool usecvars = true); native int Shavit_GetWRCount(int client, int track = -1, int style = -1, bool usecvars = true);
@ -1799,19 +1799,20 @@ native int Shavit_GetWRCount(int client, int track = -1, int style = -1, bool us
* @param track Track to retrieve WRs from. -1 to use all tracks. All bonus tracks are combined. * @param track Track to retrieve WRs from. -1 to use all tracks. All bonus tracks are combined.
* @param style Style to retrieve WRs from. -1 to use all styles. * @param style Style to retrieve WRs from. -1 to use all styles.
* @param usecvars Whether to depend on the value of `shavit_stats_mvprankones` and `shavit_stats_mvprankones_maintrack`. * @param usecvars Whether to depend on the value of `shavit_stats_mvprankones` and `shavit_stats_mvprankones_maintrack`.
* @noreturn * @return The number of WR holders. 0 if none.
*/ */
native int Shavit_GetWRHolders(int track = -1, int style = -1, bool usecvars = true); native int Shavit_GetWRHolders(int track = -1, int style = -1, bool usecvars = true);
/** /**
* Retrieves the player's rank based on how many #1 records they hold. * Retrieves the player's rank based on how many #1 records they hold.
* Requires shavit-rankings. * Requires shavit-rankings.
* Only works with MySQL 8.0+ or with MariaDB 10.2+.
* *
* @param client Client index. * @param client Client index.
* @param track Track to retrieve WRs from. -1 to use all tracks. All bonus tracks are combined. * @param track Track to retrieve WRs from. -1 to use all tracks. All bonus tracks are combined.
* @param style Style to retrieve WRs from. -1 to use all styles. * @param style Style to retrieve WRs from. -1 to use all styles.
* @param usecvars Whether to depend on the value of `shavit_stats_mvprankones` and `shavit_stats_mvprankones_maintrack`. * @param usecvars Whether to depend on the value of `shavit_stats_mvprankones` and `shavit_stats_mvprankones_maintrack`.
* @noreturn * @return The rank. 0 if none, or not supported.
*/ */
native int Shavit_GetWRHolderRank(int client, int track = -1, int style = -1, bool usecvars = true); native int Shavit_GetWRHolderRank(int client, int track = -1, int style = -1, bool usecvars = true);

View File

@ -51,7 +51,6 @@
#pragma newdecls required #pragma newdecls required
#pragma semicolon 1 #pragma semicolon 1
// uncomment when done
// #define DEBUG // #define DEBUG
enum struct ranking_t enum struct ranking_t
@ -68,6 +67,7 @@ enum struct ranking_t
char gS_MySQLPrefix[32]; char gS_MySQLPrefix[32];
Database gH_SQL = null; Database gH_SQL = null;
bool gB_HasSQLRANK = false; // whether the sql driver supports RANK()
bool gB_Stats = false; bool gB_Stats = false;
bool gB_Late = false; bool gB_Late = false;
@ -87,7 +87,6 @@ Convar gCV_LastLoginRecalculate = null;
Convar gCV_MVPRankOnes = null; Convar gCV_MVPRankOnes = null;
Convar gCV_MVPRankOnes_Main = null; Convar gCV_MVPRankOnes_Main = null;
Convar gCV_DefaultTier = null; Convar gCV_DefaultTier = null;
Convar gCV_WRRanks = null;
ranking_t gA_Rankings[MAXPLAYERS+1]; ranking_t gA_Rankings[MAXPLAYERS+1];
@ -168,7 +167,6 @@ public void OnPluginStart()
gCV_MVPRankOnes = new Convar("shavit_rankings_mvprankones", "2", "Set the players' amount of MVPs to the amount of #1 times they have.\n0 - Disabled\n1 - Enabled, for all styles.\n2 - Enabled, for default style only.\n(CS:S/CS:GO only)", 0, true, 0.0, true, 2.0); gCV_MVPRankOnes = new Convar("shavit_rankings_mvprankones", "2", "Set the players' amount of MVPs to the amount of #1 times they have.\n0 - Disabled\n1 - Enabled, for all styles.\n2 - Enabled, for default style only.\n(CS:S/CS:GO only)", 0, true, 0.0, true, 2.0);
gCV_MVPRankOnes_Main = new Convar("shavit_rankings_mvprankones_maintrack", "1", "If set to 0, all tracks will be counted for the MVP stars.\nOtherwise, only the main track will be checked.\n\nRequires \"shavit_stats_mvprankones\" set to 1 or above.\n(CS:S/CS:GO only)", 0, true, 0.0, true, 1.0); gCV_MVPRankOnes_Main = new Convar("shavit_rankings_mvprankones_maintrack", "1", "If set to 0, all tracks will be counted for the MVP stars.\nOtherwise, only the main track will be checked.\n\nRequires \"shavit_stats_mvprankones\" set to 1 or above.\n(CS:S/CS:GO only)", 0, true, 0.0, true, 1.0);
gCV_DefaultTier = new Convar("shavit_rankings_default_tier", "1", "Sets the default tier for new maps added.", 0, true, 0.0, true, 10.0); gCV_DefaultTier = new Convar("shavit_rankings_default_tier", "1", "Sets the default tier for new maps added.", 0, true, 0.0, true, 10.0);
gCV_WRRanks = new Convar("shavit_rankings_wrranks", "1", "Whether to query WR Holders rank and WR count. If you don't care about it being used for chat-rank customization, you can disable this and have less database churn.", 0, true, 0.0, true, 1.0);
Convar.AutoExecConfig(); Convar.AutoExecConfig();
@ -227,6 +225,8 @@ public void Shavit_OnDatabaseLoaded()
SetFailState("MySQL is the only supported database engine for shavit-rankings."); SetFailState("MySQL is the only supported database engine for shavit-rankings.");
} }
gH_SQL.Query(SQL_Version_Callback, "SELECT VERSION();");
char sQuery[256]; char sQuery[256];
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); 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);
@ -374,11 +374,6 @@ public void OnMapStart()
return; return;
} }
if (gCV_WRRanks.BoolValue)
{
UpdateWRHolders();
}
// Default tier. // Default tier.
// I won't repeat the same mistake blacky has done with tier 3 being default.. // I won't repeat the same mistake blacky has done with tier 3 being default..
gI_Tier = gCV_DefaultTier.IntValue; gI_Tier = gCV_DefaultTier.IntValue;
@ -500,11 +495,11 @@ void UpdateWRs(int client)
char sQuery[512]; char sQuery[512];
FormatEx(sQuery, sizeof(sQuery), FormatEx(sQuery, sizeof(sQuery),
" SELECT *, 0 as track, 0 as type FROM wrhrankmain WHERE auth = %d \ " SELECT *, 0 as track, 0 as type FROM %swrhrankmain WHERE auth = %d \
UNION SELECT *, 1 as track, 0 as type FROM wrhrankbonus WHERE auth = %d \ UNION SELECT *, 1 as track, 0 as type FROM %swrhrankbonus WHERE auth = %d \
UNION SELECT *, -1, 1 as type FROM wrhrankall WHERE auth = %d \ UNION SELECT *, -1, 1 as type FROM %swrhrankall WHERE auth = %d \
UNION SELECT *, -1, 2 as type FROM wrhrankcvar WHERE auth = %d;", UNION SELECT *, -1, 2 as type FROM %swrhrankcvar WHERE auth = %d;",
iSteamID, iSteamID, iSteamID, iSteamID); gS_MySQLPrefix, iSteamID, gS_MySQLPrefix, iSteamID, gS_MySQLPrefix, iSteamID, gS_MySQLPrefix, iSteamID);
gH_SQL.Query(SQL_GetWRs_Callback, sQuery, GetClientSerial(client)); gH_SQL.Query(SQL_GetWRs_Callback, sQuery, GetClientSerial(client));
} }
@ -512,22 +507,7 @@ public void SQL_GetWRs_Callback(Database db, DBResultSet results, const char[] e
{ {
if(results == null) if(results == null)
{ {
// Try to recreate temporary tables. LogError("SQL_GetWRs_Callback failed. Reason: %s", error);
// If the db connection drops and disconnects it might be destroying them... but idk.
if (StrContains(error, "Table ") != -1 && StrContains(error, " doesn't exist") != -1)
{
if (gB_WRsRefreshed)
{
LogError("SQL_GetWRs_Callback failed. Attempting to recreate tables. Error: %s", error);
gB_WRsRefreshed = false;
RequestFrame(UpdateWRHolders);
}
}
else
{
LogError("SQL_GetWRs_Callback failed. Reason: %s", error);
}
return; return;
} }
@ -1031,29 +1011,46 @@ public void SQL_UpdateTop100_Callback(Database db, DBResultSet results, const ch
gH_Top100Menu.ExitButton = true; gH_Top100Menu.ExitButton = true;
} }
void UpdateWRHolders() bool DoWeHaveRANK(const char[] sVersion)
{ {
// Compatible with MySQL 5.6, 5.7, 8.0 float fVersion = StringToFloat(sVersion);
if (StrContains(sVersion, "MariaDB") != -1)
{
return fVersion >= 10.2;
}
else // mysql then...
{
return fVersion >= 8.0;
}
}
public void SQL_Version_Callback(Database db, DBResultSet results, const char[] error, any data)
{
if (results == null || !results.FetchRow())
{
LogError("Timer (rankings) error! Failed to retrieve VERSION(). Reason: %s", error);
}
else
{
char sVersion[100];
results.FetchString(0, sVersion, sizeof(sVersion));
gB_HasSQLRANK = DoWeHaveRANK(sVersion);
}
char sWRHolderRankTrackQueryYuck[] = char sWRHolderRankTrackQueryYuck[] =
"CREATE TEMPORARY TABLE %s AS \ "CREATE OR REPLACE VIEW %s%s AS \
SELECT ( \ SELECT \
CASE style \ 0 as wrrank, \
WHEN @curGroup \
THEN @curRow := @curRow + 1 \
ELSE @curRow := 1 AND @curGroup := style END \
) as wrrank, \
style, auth, wrcount \ style, auth, wrcount \
FROM ( \ FROM ( \
SELECT style, auth, SUM(c) as wrcount FROM ( \ SELECT style, auth, SUM(c) as wrcount FROM ( \
SELECT style, auth, COUNT(auth) as c FROM %swrs WHERE track %c 0 GROUP BY style, auth \ SELECT style, auth, COUNT(auth) as c FROM %swrs WHERE track %c 0 GROUP BY style, auth \
) a GROUP BY style, auth ORDER BY style ASC, wrcount DESC, auth ASC \ ) a GROUP BY style, auth \
) x, \ ) x;";
(SELECT @curRow := 0, @curGroup := 0) r \
ORDER BY style ASC, wrrank ASC, auth ASC;";
// Compatible with MySQL 8.0 and SQLite // TODO: SELECT VERSION() and check...
char sWRHolderRankTrackQueryRANK[] = char sWRHolderRankTrackQueryRANK[] =
"CREATE TEMPORARY TABLE %s AS \ "CREATE OR REPLACE VIEW %s%s AS \
SELECT \ SELECT \
RANK() OVER(PARTITION BY style ORDER BY wrcount DESC, auth ASC) \ RANK() OVER(PARTITION BY style ORDER BY wrcount DESC, auth ASC) \
as wrrank, \ as wrrank, \
@ -1064,22 +1061,17 @@ void UpdateWRHolders()
) a GROUP BY style, auth \ ) a GROUP BY style, auth \
) x;"; ) x;";
// Compatible with MySQL 5.6, 5.7, 8.0
char sWRHolderRankOtherQueryYuck[] = char sWRHolderRankOtherQueryYuck[] =
"CREATE TEMPORARY TABLE %s AS \ "CREATE OR REPLACE VIEW %s%s AS \
SELECT ( \ SELECT \
@curRow := @curRow + 1 \ 0 as wrrank, \
) as wrrank, \
-1 as style, auth, wrcount \ -1 as style, auth, wrcount \
FROM ( \ FROM ( \
SELECT COUNT(*) as wrcount, auth FROM %swrs %s %s %s %s GROUP BY auth ORDER BY wrcount DESC, auth ASC \ SELECT COUNT(*) as wrcount, auth FROM %swrs %s %s %s %s GROUP BY auth \
) x, \ ) x;";
(SELECT @curRow := 0) r \
ORDER BY style ASC, wrrank ASC, auth ASC;";
// Compatible with MySQL 8.0 and SQLite // TODO: SELECT VERSION() and check...
char sWRHolderRankOtherQueryRANK[] = char sWRHolderRankOtherQueryRANK[] =
"CREATE TEMPORARY TABLE %s AS \ "CREATE OR REPLACE VIEW %s%s AS \
SELECT \ SELECT \
RANK() OVER(ORDER BY wrcount DESC, auth ASC) \ RANK() OVER(ORDER BY wrcount DESC, auth ASC) \
as wrrank, \ as wrrank, \
@ -1091,28 +1083,24 @@ void UpdateWRHolders()
char sQuery[800]; char sQuery[800];
Transaction hTransaction = new Transaction(); Transaction hTransaction = new Transaction();
hTransaction.AddQuery("DROP TABLE IF EXISTS wrhrankmain;");
FormatEx(sQuery, sizeof(sQuery), FormatEx(sQuery, sizeof(sQuery),
IsMySQLDatabase(gH_SQL) ? sWRHolderRankTrackQueryYuck : sWRHolderRankTrackQueryRANK, !gB_HasSQLRANK ? sWRHolderRankTrackQueryYuck : sWRHolderRankTrackQueryRANK,
"wrhrankmain", gS_MySQLPrefix, '='); gS_MySQLPrefix, "wrhrankmain", gS_MySQLPrefix, '=');
hTransaction.AddQuery(sQuery); hTransaction.AddQuery(sQuery);
hTransaction.AddQuery("DROP TABLE IF EXISTS wrhrankbonus;");
FormatEx(sQuery, sizeof(sQuery), FormatEx(sQuery, sizeof(sQuery),
IsMySQLDatabase(gH_SQL) ? sWRHolderRankTrackQueryYuck : sWRHolderRankTrackQueryRANK, !gB_HasSQLRANK ? sWRHolderRankTrackQueryYuck : sWRHolderRankTrackQueryRANK,
"wrhrankbonus", gS_MySQLPrefix, '>'); gS_MySQLPrefix, "wrhrankbonus", gS_MySQLPrefix, '>');
hTransaction.AddQuery(sQuery); hTransaction.AddQuery(sQuery);
hTransaction.AddQuery("DROP TABLE IF EXISTS wrhrankall;");
FormatEx(sQuery, sizeof(sQuery), FormatEx(sQuery, sizeof(sQuery),
IsMySQLDatabase(gH_SQL) ? sWRHolderRankOtherQueryYuck : sWRHolderRankOtherQueryRANK, !gB_HasSQLRANK ? sWRHolderRankOtherQueryYuck : sWRHolderRankOtherQueryRANK,
"wrhrankall", gS_MySQLPrefix, "", "", "", ""); gS_MySQLPrefix, "wrhrankall", gS_MySQLPrefix, "", "", "", "");
hTransaction.AddQuery(sQuery); hTransaction.AddQuery(sQuery);
hTransaction.AddQuery("DROP TABLE IF EXISTS wrhrankcvar;");
FormatEx(sQuery, sizeof(sQuery), FormatEx(sQuery, sizeof(sQuery),
IsMySQLDatabase(gH_SQL) ? sWRHolderRankOtherQueryYuck : sWRHolderRankOtherQueryRANK, !gB_HasSQLRANK ? sWRHolderRankOtherQueryYuck : sWRHolderRankOtherQueryRANK,
"wrhrankcvar", gS_MySQLPrefix, gS_MySQLPrefix, "wrhrankcvar", gS_MySQLPrefix,
(gCV_MVPRankOnes.IntValue == 2 || gCV_MVPRankOnes_Main.BoolValue) ? "WHERE" : "", (gCV_MVPRankOnes.IntValue == 2 || gCV_MVPRankOnes_Main.BoolValue) ? "WHERE" : "",
(gCV_MVPRankOnes.IntValue == 2) ? "style = 0" : "", (gCV_MVPRankOnes.IntValue == 2) ? "style = 0" : "",
(gCV_MVPRankOnes.IntValue == 2 && gCV_MVPRankOnes_Main.BoolValue) ? "AND" : "", (gCV_MVPRankOnes.IntValue == 2 && gCV_MVPRankOnes_Main.BoolValue) ? "AND" : "",
@ -1126,10 +1114,11 @@ public void Trans_WRHolderRankTablesSuccess(Database db, any data, int numQuerie
{ {
char sQuery[1024]; char sQuery[1024];
FormatEx(sQuery, sizeof(sQuery), FormatEx(sQuery, sizeof(sQuery),
" SELECT 0 as type, 0 as track, style, COUNT(DISTINCT auth) FROM wrhrankmain GROUP BY STYLE \ " SELECT 0 as type, 0 as track, style, COUNT(DISTINCT auth) FROM %swrhrankmain GROUP BY STYLE \
UNION SELECT 0 as type, 1 as track, style, COUNT(DISTINCT auth) FROM wrhrankbonus GROUP BY STYLE \ UNION SELECT 0 as type, 1 as track, style, COUNT(DISTINCT auth) FROM %swrhrankbonus GROUP BY STYLE \
UNION SELECT 1 as type, -1 as track, -1 as style, COUNT(DISTINCT auth) FROM wrhrankall \ UNION SELECT 1 as type, -1 as track, -1 as style, COUNT(DISTINCT auth) FROM %swrhrankall \
UNION SELECT 2 as type, -1 as track, -1 as style, COUNT(DISTINCT auth) FROM wrhrankcvar;"); UNION SELECT 2 as type, -1 as track, -1 as style, COUNT(DISTINCT auth) FROM %swrhrankcvar;",
gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix);
gH_SQL.Query(SQL_GetWRHolders_Callback, sQuery); gH_SQL.Query(SQL_GetWRHolders_Callback, sQuery);
} }