mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-26 06:22:26 +01:00
Change SSPRISM to use the new DBCore (#21543)
Ported almost all of it from TG Co-authored-by: Werner <Arrow768@users.noreply.github.com>
This commit is contained in:
@@ -370,7 +370,7 @@ SUBSYSTEM_DEF(dbcore)
|
||||
*
|
||||
*/
|
||||
/datum/db_query_template/proc/Execute(arguments, allow_during_shutdown=FALSE)
|
||||
var/datum/db_query/query = SSdbcore.NewQuery(sql, arguments, allow_during_shutdown)
|
||||
var/datum/db_query/query = SSdbcore.NewQuery(sql, arguments, allow_during_shutdown)
|
||||
return query.Execute()
|
||||
|
||||
/datum/db_query
|
||||
@@ -548,6 +548,107 @@ SUBSYSTEM_DEF(dbcore)
|
||||
while(status < DB_QUERY_FINISHED)
|
||||
stoplag()
|
||||
|
||||
|
||||
/** QuerySelect
|
||||
Run a list of query datums in parallel, blocking until they all complete.
|
||||
* queries - List of queries or single query datum to run.
|
||||
* warn - Controls rather warn_execute() or Execute() is called.
|
||||
* qdel - If you don't care about the result or checking for errors, you can have the queries be deleted afterwards.
|
||||
This can be combined with invoke_async as a way of running queries async without having to care about waiting for them to finish so they can be deleted,
|
||||
however you should probably just use FireAndForget instead if it's just a single query.
|
||||
*/
|
||||
/datum/controller/subsystem/dbcore/proc/QuerySelect(list/queries, warn = FALSE, qdel = FALSE)
|
||||
if (!islist(queries))
|
||||
if (!istype(queries, /datum/db_query))
|
||||
CRASH("Invalid query passed to QuerySelect: [queries]")
|
||||
queries = list(queries)
|
||||
else
|
||||
queries = queries.Copy() //we don't want to hide bugs in the parent caller by removing invalid values from this list.
|
||||
|
||||
for (var/datum/db_query/query as anything in queries)
|
||||
if (!istype(query))
|
||||
queries -= query
|
||||
stack_trace("Invalid query passed to QuerySelect: `[query]` [REF(query)]")
|
||||
continue
|
||||
|
||||
if (warn)
|
||||
INVOKE_ASYNC(query, TYPE_PROC_REF(/datum/db_query, warn_execute))
|
||||
else
|
||||
INVOKE_ASYNC(query, TYPE_PROC_REF(/datum/db_query, Execute))
|
||||
|
||||
for (var/datum/db_query/query as anything in queries)
|
||||
query.sync()
|
||||
if (qdel)
|
||||
qdel(query)
|
||||
|
||||
/*
|
||||
Takes a list of rows (each row being an associated list of column => value) and inserts them via a single mass query.
|
||||
Rows missing columns present in other rows will resolve to SQL NULL
|
||||
You are expected to do your own escaping of the data, and expected to provide your own quotes for strings.
|
||||
The duplicate_key arg can be true to automatically generate this part of the query
|
||||
or set to a string that is appended to the end of the query
|
||||
Ignore_errors instructes mysql to continue inserting rows if some of them have errors.
|
||||
the erroneous row(s) aren't inserted and there isn't really any way to know why or why errored
|
||||
*/
|
||||
/datum/controller/subsystem/dbcore/proc/MassInsert(table, list/rows, duplicate_key = FALSE, ignore_errors = FALSE, warn = FALSE, async = TRUE, special_columns = null)
|
||||
if (!table || !rows || !istype(rows))
|
||||
return
|
||||
|
||||
// Prepare column list
|
||||
var/list/columns = list()
|
||||
var/list/has_question_mark = list()
|
||||
for (var/list/row in rows)
|
||||
for (var/column in row)
|
||||
columns[column] = "?"
|
||||
has_question_mark[column] = TRUE
|
||||
for (var/column in special_columns)
|
||||
columns[column] = special_columns[column]
|
||||
has_question_mark[column] = findtext(special_columns[column], "?")
|
||||
|
||||
// Prepare SQL query full of placeholders
|
||||
var/list/query_parts = list("INSERT")
|
||||
if (ignore_errors)
|
||||
query_parts += " IGNORE"
|
||||
query_parts += " INTO "
|
||||
query_parts += table
|
||||
query_parts += "\n([columns.Join(", ")])\nVALUES"
|
||||
|
||||
var/list/arguments = list()
|
||||
var/has_row = FALSE
|
||||
for (var/list/row in rows)
|
||||
if (has_row)
|
||||
query_parts += ","
|
||||
query_parts += "\n ("
|
||||
var/has_col = FALSE
|
||||
for (var/column in columns)
|
||||
if (has_col)
|
||||
query_parts += ", "
|
||||
if (has_question_mark[column])
|
||||
var/name = "p[arguments.len]"
|
||||
query_parts += replacetext(columns[column], "?", ":[name]")
|
||||
arguments[name] = row[column]
|
||||
else
|
||||
query_parts += columns[column]
|
||||
has_col = TRUE
|
||||
query_parts += ")"
|
||||
has_row = TRUE
|
||||
|
||||
if (duplicate_key == TRUE)
|
||||
var/list/column_list = list()
|
||||
for (var/column in columns)
|
||||
column_list += "[column] = VALUES([column])"
|
||||
query_parts += "\nON DUPLICATE KEY UPDATE [column_list.Join(", ")]"
|
||||
else if (duplicate_key != FALSE)
|
||||
query_parts += duplicate_key
|
||||
|
||||
var/datum/db_query/Query = NewQuery(query_parts.Join(), arguments)
|
||||
if (warn)
|
||||
. = Query.warn_execute(async)
|
||||
else
|
||||
. = Query.Execute(async)
|
||||
qdel(Query)
|
||||
|
||||
|
||||
/**
|
||||
* process
|
||||
*
|
||||
|
||||
@@ -53,12 +53,18 @@ SUBSYSTEM_DEF(stickyban)
|
||||
/datum/controller/subsystem/stickyban/proc/Populatedbcache()
|
||||
var/newdbcache = list() //so if we runtime or the db connection dies we don't kill the existing cache
|
||||
|
||||
var/DBQuery/query_stickybans = GLOB.dbcon.NewQuery("SELECT ckey, reason, banning_admin, datetime FROM ss13_stickyban ORDER BY ckey")
|
||||
var/DBQuery/query_ckey_matches = GLOB.dbcon.NewQuery("SELECT stickyban, matched_ckey, first_matched, last_matched, exempt FROM ss13_stickyban_matched_ckey ORDER BY first_matched")
|
||||
var/DBQuery/query_cid_matches = GLOB.dbcon.NewQuery("SELECT stickyban, matched_cid, first_matched, last_matched FROM ss13_stickyban_matched_cid ORDER BY first_matched")
|
||||
var/DBQuery/query_ip_matches = GLOB.dbcon.NewQuery("SELECT stickyban, INET_NTOA(matched_ip), first_matched, last_matched FROM ss13_stickyban_matched_ip ORDER BY first_matched")
|
||||
var/datum/db_query/query_stickybans = SSdbcore.NewQuery("SELECT ckey, reason, banning_admin, datetime FROM ss13_stickyban ORDER BY ckey")
|
||||
var/datum/db_query/query_ckey_matches = SSdbcore.NewQuery("SELECT stickyban, matched_ckey, first_matched, last_matched, exempt FROM ss13_stickyban_matched_ckey ORDER BY first_matched")
|
||||
var/datum/db_query/query_cid_matches = SSdbcore.NewQuery("SELECT stickyban, matched_cid, first_matched, last_matched FROM ss13_stickyban_matched_cid ORDER BY first_matched")
|
||||
var/datum/db_query/query_ip_matches = SSdbcore.NewQuery("SELECT stickyban, INET_NTOA(matched_ip), first_matched, last_matched FROM ss13_stickyban_matched_ip ORDER BY first_matched")
|
||||
|
||||
if (!query_stickybans.Execute())
|
||||
SSdbcore.QuerySelect(list(query_stickybans, query_ckey_matches, query_cid_matches, query_ip_matches))
|
||||
|
||||
if (query_stickybans.last_error)
|
||||
qdel(query_stickybans)
|
||||
qdel(query_ckey_matches)
|
||||
qdel(query_cid_matches)
|
||||
qdel(query_ip_matches)
|
||||
return
|
||||
|
||||
while (query_stickybans.NextRow())
|
||||
@@ -74,7 +80,7 @@ SUBSYSTEM_DEF(stickyban)
|
||||
newdbcache["[query_stickybans.item[1]]"] = ban
|
||||
|
||||
|
||||
if (query_ckey_matches.Execute())
|
||||
if (!query_ckey_matches.last_error)
|
||||
while (query_ckey_matches.NextRow())
|
||||
var/list/match = list()
|
||||
|
||||
@@ -92,7 +98,7 @@ SUBSYSTEM_DEF(stickyban)
|
||||
keys = ban[text2num(query_ckey_matches.item[5]) ? "whitelist" : "keys"] = list()
|
||||
keys[query_ckey_matches.item[2]] = match
|
||||
|
||||
if (query_cid_matches.Execute())
|
||||
if (!query_cid_matches.last_error)
|
||||
while (query_cid_matches.NextRow())
|
||||
var/list/match = list()
|
||||
|
||||
@@ -110,7 +116,7 @@ SUBSYSTEM_DEF(stickyban)
|
||||
computer_ids[query_cid_matches.item[2]] = match
|
||||
|
||||
|
||||
if (query_ip_matches.Execute())
|
||||
if (!query_ip_matches.last_error)
|
||||
while (query_ip_matches.NextRow())
|
||||
var/list/match = list()
|
||||
|
||||
@@ -130,6 +136,11 @@ SUBSYSTEM_DEF(stickyban)
|
||||
dbcache = newdbcache
|
||||
dbcacheexpire = world.time+STICKYBAN_DB_CACHE_TIME
|
||||
|
||||
qdel(query_stickybans)
|
||||
qdel(query_ckey_matches)
|
||||
qdel(query_cid_matches)
|
||||
qdel(query_ip_matches)
|
||||
|
||||
/datum/controller/subsystem/stickyban/proc/import_raw_stickyban_to_db(ckey, list/ban)
|
||||
. = FALSE
|
||||
if (!ban["admin"])
|
||||
@@ -137,9 +148,14 @@ SUBSYSTEM_DEF(stickyban)
|
||||
if (!ban["message"])
|
||||
ban["message"] = "Evasion"
|
||||
|
||||
var/DBQuery/query_create_stickyban = GLOB.dbcon.NewQuery("INSERT IGNORE INTO ss13_stickyban (ckey, reason, banning_admin) VALUES ('[sanitizeSQL(ckey)]', '[sanitizeSQL(ban["message"])]', '[sanitizeSQL(ban["admin"])]')")
|
||||
if (!query_create_stickyban.Execute())
|
||||
var/datum/db_query/query_create_stickyban = SSdbcore.NewQuery(
|
||||
"INSERT IGNORE INTO ss13_stickyban (ckey, reason, banning_admin) VALUES (:ckey, :message, :admin)",
|
||||
list("ckey" = ckey, "message" = ban["message"], "admin" = ban["admin"])
|
||||
)
|
||||
if (!query_create_stickyban.warn_execute())
|
||||
qdel(query_create_stickyban)
|
||||
return
|
||||
qdel(query_create_stickyban)
|
||||
|
||||
var/list/sqlckeys = list()
|
||||
var/list/sqlcids = list()
|
||||
@@ -149,8 +165,8 @@ SUBSYSTEM_DEF(stickyban)
|
||||
var/list/keys = splittext(ban["keys"], ",")
|
||||
for (var/key in keys)
|
||||
var/list/sqlckey = list()
|
||||
sqlckey["stickyban"] = "'[sanitizeSQL(ckey)]'"
|
||||
sqlckey["matched_ckey"] = "'[sanitizeSQL(ckey(key))]'"
|
||||
sqlckey["stickyban"] = ckey
|
||||
sqlckey["matched_ckey"] = ckey(key)
|
||||
sqlckey["exempt"] = FALSE
|
||||
sqlckeys[++sqlckeys.len] = sqlckey
|
||||
|
||||
@@ -158,8 +174,8 @@ SUBSYSTEM_DEF(stickyban)
|
||||
var/list/keys = splittext(ban["whitelist"], ",")
|
||||
for (var/key in keys)
|
||||
var/list/sqlckey = list()
|
||||
sqlckey["stickyban"] = "'[sanitizeSQL(ckey)]'"
|
||||
sqlckey["matched_ckey"] = "'[sanitizeSQL(ckey(key))]'"
|
||||
sqlckey["stickyban"] = ckey
|
||||
sqlckey["matched_ckey"] = ckey(key)
|
||||
sqlckey["exempt"] = TRUE
|
||||
sqlckeys[++sqlckeys.len] = sqlckey
|
||||
|
||||
@@ -167,26 +183,26 @@ SUBSYSTEM_DEF(stickyban)
|
||||
var/list/cids = splittext(ban["computer_id"], ",")
|
||||
for (var/cid in cids)
|
||||
var/list/sqlcid = list()
|
||||
sqlcid["stickyban"] = "'[sanitizeSQL(ckey)]'"
|
||||
sqlcid["matched_cid"] = "'[sanitizeSQL(cid)]'"
|
||||
sqlcid["stickyban"] = ckey
|
||||
sqlcid["matched_cid"] = cid
|
||||
sqlcids[++sqlcids.len] = sqlcid
|
||||
|
||||
if (ban["IP"])
|
||||
var/list/ips = splittext(ban["IP"], ",")
|
||||
for (var/ip in ips)
|
||||
var/list/sqlip = list()
|
||||
sqlip["stickyban"] = "'[sanitizeSQL(ckey)]'"
|
||||
sqlip["matched_ip"] = "'[sanitizeSQL(ip)]'"
|
||||
sqlip["stickyban"] = ckey
|
||||
sqlip["matched_ip"] = ip
|
||||
sqlips[++sqlips.len] = sqlip
|
||||
|
||||
if (length(sqlckeys))
|
||||
GLOB.dbcon.MassInsert("ss13_stickyban_matched_ckey", sqlckeys, FALSE, TRUE)
|
||||
SSdbcore.MassInsert("ss13_stickyban_matched_ckey", sqlckeys, ignore_errors = TRUE)
|
||||
|
||||
if (length(sqlcids))
|
||||
GLOB.dbcon.MassInsert("ss13_stickyban_matched_cid", sqlcids, FALSE, TRUE)
|
||||
SSdbcore.MassInsert("ss13_stickyban_matched_cid", sqlcids, ignore_errors = TRUE)
|
||||
|
||||
if (length(sqlips))
|
||||
GLOB.dbcon.MassInsert("ss13_stickyban_matched_ip", sqlips, FALSE, TRUE)
|
||||
SSdbcore.MassInsert("ss13_stickyban_matched_ip", sqlips, ignore_errors = TRUE)
|
||||
|
||||
|
||||
return TRUE
|
||||
|
||||
Reference in New Issue
Block a user