mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
Removes BSQL (#8697)
* Update rust_g.dm * thing * thing * thing * thing * thing * t * t * Update random_books.dm * Update new_player.dm * Update client_procs.dm * f * uwu * Update dbcore.dm * uwu * Update permissionedit.dm * Update dbcore.dm * Update dbcore.dm * Update blackbox.dm * Update dbcore.dm * d * uwu * Parameterize ipintel * Update lib_machines.dm * Parameterize stickyban * Update sql_message_system.dm * f * thing * thing * polls * Parameterize some of sql_ban_system * f * Update dbcore.dm * Parameterize ban check * Parameterize jobban creation * uwu * uwu * Parameterize edit ban * git * uwu * uwu * Update install_rust_g.sh * Remove libmariadb.dll * Update deploy.sh * uwu * Avoid extra __detect_rust_g proccalls * uwu * ree * Remove libmariadb.so download script * boom * Turdis * finally * sneaky * night night * list( * token * Update dbcore.dm * uwu * Improve readability on a query * uwu * Update sql_message_system.dm * Update sql_message_system.dm * Fix Malformed SQL Queries When Editing Admin Permissions (#51625) * fixes * s * Update antag_token.dm * Update create_poll.dm * Update lib_machines.dm * Update lib_machines.dm * Update client_procs.dm * Update rust_g.dm * Update code/__DEFINES/rust_g.dm Co-authored-by: alexkar598 <25136265+alexkar598@users.noreply.github.com> * Update sql_message_system.dm * Update sql_message_system.dm * Update sql_message_system.dm * Update sql_message_system.dm * Update code/controllers/subsystem/blackbox.dm Co-authored-by: alexkar598 <25136265+alexkar598@users.noreply.github.com> * Update code/controllers/subsystem/blackbox.dm Co-authored-by: alexkar598 <25136265+alexkar598@users.noreply.github.com> * Update turdis.yml * Update client_procs.dm * Update client_procs.dm * debug logging * Update client_procs.dm * Update client_procs.dm * Update yogstation/code/modules/client/client_procs.dm Co-authored-by: alexkar598 <25136265+alexkar598@users.noreply.github.com> * Update sql_ban_system.dm Co-authored-by: Tad Hardesty <tad@platymuus.com> Co-authored-by: Bobbahbrown <bobbahbrown@gmail.com> Co-authored-by: alexkar598 <25136265+alexkar598@users.noreply.github.com>
This commit is contained in:
@@ -12,20 +12,20 @@ SUBSYSTEM_DEF(achievements)
|
||||
var/datum/achievement/A = new i
|
||||
achievements[A] = A.id
|
||||
|
||||
var/datum/DBQuery/medalQuery = SSdbcore.NewQuery("SELECT name, descr FROM [format_table_name("achievements")] WHERE id = '[A.id]'") // No sanitation of A is needed for these calls because we instantiated A right here in this proc.
|
||||
var/datum/DBQuery/medalQuery = SSdbcore.NewQuery("SELECT name, descr FROM [format_table_name("achievements")] WHERE id = :id", list("id" = A.id)) // No sanitation of A is needed for these calls because we instantiated A right here in this proc.
|
||||
medalQuery.Execute()
|
||||
if(!medalQuery.NextRow())
|
||||
var/datum/DBQuery/medalQuery2 = SSdbcore.NewQuery("INSERT INTO [format_table_name("achievements")] (name, id, descr) VALUES ('[A.name]', '[A.id]', '[A.desc]')")
|
||||
var/datum/DBQuery/medalQuery2 = SSdbcore.NewQuery("INSERT INTO [format_table_name("achievements")] (name, id, descr) VALUES (:name, :id, :desc)", list("name" = A.name, "id" = A.id, "desc" = A.desc))
|
||||
medalQuery2.Execute()
|
||||
qdel(medalQuery2)
|
||||
else if(medalQuery.item[1] != A.name || medalQuery.item[2] != A.desc)
|
||||
var/datum/DBQuery/medalQuery2 = SSdbcore.NewQuery("UPDATE [format_table_name("achievements")] SET name = '[A.name]', descr = '[A.desc]' WHERE id = '[A.id]'")
|
||||
var/datum/DBQuery/medalQuery2 = SSdbcore.NewQuery("UPDATE [format_table_name("achievements")] SET name = :name, descr = :desc WHERE id = :id", list("name" = A.name, "desc" = A.desc, "id" = A.id))
|
||||
medalQuery2.Execute()
|
||||
qdel(medalQuery2)
|
||||
|
||||
|
||||
qdel(medalQuery)
|
||||
|
||||
|
||||
|
||||
|
||||
var/datum/DBQuery/ridOldChieves = SSdbcore.NewQuery("SELECT id FROM [format_table_name("achievements")]")
|
||||
ridOldChieves.Execute()
|
||||
while(ridOldChieves.NextRow())
|
||||
@@ -38,9 +38,9 @@ SUBSYSTEM_DEF(achievements)
|
||||
break
|
||||
if(!found_achievement)
|
||||
log_sql("Old achievement [id] found in database, removing")
|
||||
var/datum/DBQuery/getRidOfOldStuff = SSdbcore.NewQuery("DELETE FROM [format_table_name("achievements")] WHERE id = '[id]'")
|
||||
var/datum/DBQuery/getRidOfOldStuff = SSdbcore.NewQuery("DELETE FROM [format_table_name("achievements")] WHERE id = :id", list("id" = id))
|
||||
getRidOfOldStuff.Execute()
|
||||
var/datum/DBQuery/ridTheOtherTableAsWell = SSdbcore.NewQuery("DELETE FROM [format_table_name("earned_achievements")] WHERE id = '[id]'")
|
||||
var/datum/DBQuery/ridTheOtherTableAsWell = SSdbcore.NewQuery("DELETE FROM [format_table_name("earned_achievements")] WHERE id = :id", list("id" = id))
|
||||
ridTheOtherTableAsWell.Execute()
|
||||
qdel(ridTheOtherTableAsWell)
|
||||
qdel(getRidOfOldStuff)
|
||||
@@ -75,7 +75,7 @@ SUBSYSTEM_DEF(achievements)
|
||||
if(istype(achievement,/datum/achievement/greentext) && achievementPath != /datum/achievement/greentext)
|
||||
unlock_achievement(/datum/achievement/greentext,C) // Oooh, a little bit recursive!
|
||||
if(!has_achievement(achievementPath, C))
|
||||
var/datum/DBQuery/medalQuery = SSdbcore.NewQuery("INSERT INTO [format_table_name("earned_achievements")] (ckey, id) VALUES ('[ckey(C.ckey)]', '[initial(achievement.id)]')")
|
||||
var/datum/DBQuery/medalQuery = SSdbcore.NewQuery("INSERT INTO [format_table_name("earned_achievements")] (ckey, id) VALUES (:ckey, :id)", list("ckey" = ckey(C.ckey), "id" = initial(achievement.id)))
|
||||
medalQuery.Execute()
|
||||
qdel(medalQuery)
|
||||
cached_achievements[C.ckey] += achievement
|
||||
@@ -88,7 +88,7 @@ SUBSYSTEM_DEF(achievements)
|
||||
/datum/controller/subsystem/achievements/proc/has_achievement(achievementPath, client/C)
|
||||
var/datum/achievement/achievement = get_achievement(achievementPath)
|
||||
if(!achievement)
|
||||
log_sql("Achievement [achievementPath] not found in list of achievements when checking for [C.ckey]")
|
||||
log_sql("Achievement [achievementPath] not found in list of achievements when checking for [C.ckey]")
|
||||
return FALSE
|
||||
if(!cached_achievements[C.ckey])
|
||||
cache_achievements(C)
|
||||
@@ -96,7 +96,7 @@ SUBSYSTEM_DEF(achievements)
|
||||
return (achievement in cached_achievements[C.ckey])
|
||||
|
||||
/datum/controller/subsystem/achievements/proc/cache_achievements(client/C)
|
||||
var/datum/DBQuery/cacheQuery = SSdbcore.NewQuery("SELECT id FROM [format_table_name("earned_achievements")] WHERE ckey = '[ckey(C.ckey)]'")
|
||||
var/datum/DBQuery/cacheQuery = SSdbcore.NewQuery("SELECT id FROM [format_table_name("earned_achievements")] WHERE ckey = :ckey", list("ckey" = ckey(C.ckey)))
|
||||
cacheQuery.Execute()
|
||||
cached_achievements[C.ckey] = list()
|
||||
while(cacheQuery.NextRow())
|
||||
|
||||
@@ -45,7 +45,17 @@ SUBSYSTEM_DEF(blackbox)
|
||||
if(M.client)
|
||||
playercount += 1
|
||||
var/admincount = GLOB.admins.len
|
||||
var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port, round_id) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]')")
|
||||
var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port, round_id)
|
||||
VALUES (:playercount, :admincount, :time, INET_ATON(:server_ip), :server_port, :round_id)
|
||||
"}, list(
|
||||
"playercount" = playercount,
|
||||
"admincount" = admincount,
|
||||
"time" = SQLtime(),
|
||||
"server_ip" = world.internet_address || "0",
|
||||
"server_port" = world.port,
|
||||
"round_id" = GLOB.round_id,
|
||||
))
|
||||
query_record_playercount.Execute()
|
||||
qdel(query_record_playercount)
|
||||
|
||||
@@ -89,18 +99,23 @@ SUBSYSTEM_DEF(blackbox)
|
||||
if (!SSdbcore.Connect())
|
||||
return
|
||||
|
||||
var/list/special_columns = list(
|
||||
"datetime" = "NOW()"
|
||||
)
|
||||
|
||||
var/list/sqlrowlist = list()
|
||||
|
||||
for (var/datum/feedback_variable/FV in feedback)
|
||||
var/sqlversion = 1
|
||||
if(FV.key in versions)
|
||||
sqlversion = versions[FV.key]
|
||||
sqlrowlist += list(list("datetime" = "Now()", "round_id" = GLOB.round_id, "key_name" = "'[sanitizeSQL(FV.key)]'", "key_type" = "'[FV.key_type]'", "version" = "[sqlversion]", "json" = "'[sanitizeSQL(json_encode(FV.json))]'"))
|
||||
|
||||
sqlrowlist += list(list(
|
||||
"key_type" = FV.key_type,
|
||||
"round_id" = GLOB.round_id,
|
||||
"key_name" = FV.key,
|
||||
"version" = versions[FV.key] || 1,
|
||||
"json" = json_encode(FV.json)
|
||||
))
|
||||
if (!length(sqlrowlist))
|
||||
return
|
||||
|
||||
SSdbcore.MassInsert(format_table_name("feedback"), sqlrowlist, ignore_errors = TRUE, delayed = TRUE)
|
||||
SSdbcore.MassInsert(format_table_name("feedback"), sqlrowlist, ignore_errors = TRUE, delayed = TRUE, special_columns = special_columns)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/Seal()
|
||||
if(sealed)
|
||||
@@ -286,51 +301,36 @@ Versioning
|
||||
first_death["area"] = "[AREACOORD(L)]"
|
||||
first_death["damage"] = "<font color='#FF5555'>[L.getBruteLoss()]</font>/<font color='orange'>[L.getFireLoss()]</font>/<font color='lightgreen'>[L.getToxLoss()]</font>/<font color='lightblue'>[L.getOxyLoss()]</font>/<font color='pink'>[L.getCloneLoss()]</font>"
|
||||
first_death["last_words"] = L.last_words
|
||||
var/sqlname = L.real_name
|
||||
var/sqlkey = L.ckey
|
||||
var/sqljob = L.mind.assigned_role
|
||||
var/sqlspecial = L.mind.special_role
|
||||
var/sqlpod = get_area_name(L, TRUE)
|
||||
var/laname = L.lastattacker
|
||||
var/lakey = L.lastattackerckey
|
||||
var/sqlbrute = L.getBruteLoss()
|
||||
var/sqlfire = L.getFireLoss()
|
||||
var/sqlbrain = L.getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
var/sqloxy = L.getOxyLoss()
|
||||
var/sqltox = L.getToxLoss()
|
||||
var/sqlclone = L.getCloneLoss()
|
||||
var/sqlstamina = L.getStaminaLoss()
|
||||
var/x_coord = L.x
|
||||
var/y_coord = L.y
|
||||
var/z_coord = L.z
|
||||
var/last_words = L.last_words
|
||||
var/suicide = L.suiciding
|
||||
var/map = SSmapping.config.map_name
|
||||
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
|
||||
sqlname = sanitizeSQL(sqlname)
|
||||
sqlkey = sanitizeSQL(sqlkey)
|
||||
sqljob = sanitizeSQL(sqljob)
|
||||
sqlspecial = sanitizeSQL(sqlspecial)
|
||||
sqlpod = sanitizeSQL(sqlpod)
|
||||
laname = sanitizeSQL(laname)
|
||||
lakey = sanitizeSQL(lakey)
|
||||
sqlbrute = sanitizeSQL(sqlbrute)
|
||||
sqlfire = sanitizeSQL(sqlfire)
|
||||
sqlbrain = sanitizeSQL(sqlbrain)
|
||||
sqloxy = sanitizeSQL(sqloxy)
|
||||
sqltox = sanitizeSQL(sqltox)
|
||||
sqlclone = sanitizeSQL(sqlclone)
|
||||
sqlstamina = sanitizeSQL(sqlstamina)
|
||||
x_coord = sanitizeSQL(x_coord)
|
||||
y_coord = sanitizeSQL(y_coord)
|
||||
z_coord = sanitizeSQL(z_coord)
|
||||
last_words = sanitizeSQL(last_words)
|
||||
suicide = sanitizeSQL(suicide)
|
||||
map = sanitizeSQL(map)
|
||||
var/datum/DBQuery/query_report_death = SSdbcore.NewQuery("INSERT INTO [format_table_name("death")] (pod, x_coord, y_coord, z_coord, mapname, server_ip, server_port, round_id, tod, job, special, name, byondkey, laname, lakey, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, last_words, suicide) VALUES ('[sqlpod]', '[x_coord]', '[y_coord]', '[z_coord]', '[map]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', [GLOB.round_id], '[SQLtime()]', '[sqljob]', '[sqlspecial]', '[sqlname]', '[sqlkey]', '[laname]', '[lakey]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[last_words]', [suicide])")
|
||||
var/datum/DBQuery/query_report_death = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("death")] (pod, x_coord, y_coord, z_coord, mapname, server_ip, server_port, round_id, tod, job, special, name, byondkey, laname, lakey, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, last_words, suicide)
|
||||
VALUES (:pod, :x_coord, :y_coord, :z_coord, :map, INET_ATON(:internet_address), :port, :round_id, :time, :job, :special, :name, :key, :laname, :lakey, :brute, :fire, :brain, :oxy, :tox, :clone, :stamina, :last_words, :suicide)
|
||||
"}, list(
|
||||
"name" = L.real_name,
|
||||
"key" = L.ckey,
|
||||
"job" = L.mind.assigned_role,
|
||||
"special" = L.mind.special_role,
|
||||
"pod" = get_area_name(L, TRUE),
|
||||
"laname" = L.lastattacker,
|
||||
"lakey" = L.lastattackerckey,
|
||||
"brute" = L.getBruteLoss(),
|
||||
"fire" = L.getFireLoss(),
|
||||
"brain" = L.getOrganLoss(ORGAN_SLOT_BRAIN) || BRAIN_DAMAGE_DEATH, //getOrganLoss returns null without a brain but a value is required for this column
|
||||
"oxy" = L.getOxyLoss(),
|
||||
"tox" = L.getToxLoss(),
|
||||
"clone" = L.getCloneLoss(),
|
||||
"stamina" = L.getStaminaLoss(),
|
||||
"x_coord" = L.x,
|
||||
"y_coord" = L.y,
|
||||
"z_coord" = L.z,
|
||||
"last_words" = L.last_words,
|
||||
"suicide" = L.suiciding,
|
||||
"map" = SSmapping.config.map_name,
|
||||
"internet_address" = world.internet_address || "0",
|
||||
"port" = world.port,
|
||||
"round_id" = GLOB.round_id,
|
||||
"time" = SQLtime(),
|
||||
))
|
||||
if(query_report_death)
|
||||
query_report_death.Execute(async = TRUE)
|
||||
qdel(query_report_death)
|
||||
|
||||
@@ -14,8 +14,7 @@ SUBSYSTEM_DEF(dbcore)
|
||||
var/last_error
|
||||
var/list/active_queries = list()
|
||||
|
||||
var/datum/BSQL_Connection/connection
|
||||
var/datum/BSQL_Operation/connectOperation
|
||||
var/connection // Arbitrary handle returned from rust_g.
|
||||
|
||||
/datum/controller/subsystem/dbcore/Initialize()
|
||||
//We send warnings to the admins during subsystem init, as the clients will be New'd and messages
|
||||
@@ -40,24 +39,25 @@ SUBSYSTEM_DEF(dbcore)
|
||||
|
||||
/datum/controller/subsystem/dbcore/Recover()
|
||||
connection = SSdbcore.connection
|
||||
connectOperation = SSdbcore.connectOperation
|
||||
|
||||
/datum/controller/subsystem/dbcore/Shutdown()
|
||||
//This is as close as we can get to the true round end before Disconnect() without changing where it's called, defeating the reason this is a subsystem
|
||||
if(SSdbcore.Connect())
|
||||
var/datum/DBQuery/query_round_shutdown = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET shutdown_datetime = Now(), end_state = '[sanitizeSQL(SSticker.end_state)]' WHERE id = [GLOB.round_id]")
|
||||
var/datum/DBQuery/query_round_shutdown = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("round")] SET shutdown_datetime = Now(), end_state = :end_state WHERE id = :round_id",
|
||||
list("end_state" = SSticker.end_state, "round_id" = GLOB.round_id)
|
||||
)
|
||||
query_round_shutdown.Execute()
|
||||
qdel(query_round_shutdown)
|
||||
if(IsConnected())
|
||||
Disconnect()
|
||||
world.BSQL_Shutdown()
|
||||
|
||||
//nu
|
||||
/datum/controller/subsystem/dbcore/can_vv_get(var_name)
|
||||
return var_name != NAMEOF(src, connection) && var_name != NAMEOF(src, active_queries) && var_name != NAMEOF(src, connectOperation) && ..()
|
||||
return var_name != NAMEOF(src, connection) && var_name != NAMEOF(src, active_queries) && ..()
|
||||
|
||||
/datum/controller/subsystem/dbcore/vv_edit_var(var_name, var_value)
|
||||
if(var_name == NAMEOF(src, connection) || var_name == NAMEOF(src, connectOperation))
|
||||
if(var_name == NAMEOF(src, connection))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -80,26 +80,28 @@ SUBSYSTEM_DEF(dbcore)
|
||||
var/db = CONFIG_GET(string/feedback_database)
|
||||
var/address = CONFIG_GET(string/address)
|
||||
var/port = CONFIG_GET(number/port)
|
||||
var/timeout = max(CONFIG_GET(number/async_query_timeout), CONFIG_GET(number/blocking_query_timeout))
|
||||
var/thread_limit = CONFIG_GET(number/bsql_thread_limit)
|
||||
|
||||
connection = new /datum/BSQL_Connection(BSQL_CONNECTION_TYPE_MARIADB, CONFIG_GET(number/async_query_timeout), CONFIG_GET(number/blocking_query_timeout), CONFIG_GET(number/bsql_thread_limit))
|
||||
var/error
|
||||
if(QDELETED(connection))
|
||||
connection = null
|
||||
error = last_error
|
||||
var/result = json_decode(rustg_sql_connect_pool(json_encode(list(
|
||||
"host" = address,
|
||||
"port" = port,
|
||||
"user" = user,
|
||||
"pass" = pass,
|
||||
"db_name" = db,
|
||||
"max_threads" = 5,
|
||||
"read_timeout" = timeout,
|
||||
"write_timeout" = timeout,
|
||||
"max_threads" = thread_limit,
|
||||
))))
|
||||
. = (result["status"] == "ok")
|
||||
if (.)
|
||||
connection = result["handle"]
|
||||
else
|
||||
SSdbcore.last_error = null
|
||||
connectOperation = connection.BeginConnect(address, port, user, pass, db)
|
||||
if(SSdbcore.last_error)
|
||||
CRASH(SSdbcore.last_error)
|
||||
UNTIL(connectOperation.IsComplete())
|
||||
error = connectOperation.GetError()
|
||||
. = !error
|
||||
if (!.)
|
||||
last_error = error
|
||||
log_sql("Connect() failed | [error]")
|
||||
connection = null
|
||||
last_error = result["data"]
|
||||
log_sql("Connect() failed | [last_error]")
|
||||
++failed_connections
|
||||
QDEL_NULL(connection)
|
||||
QDEL_NULL(connectOperation)
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/CheckSchemaVersion()
|
||||
if(CONFIG_GET(flag/sql_enabled))
|
||||
@@ -125,50 +127,49 @@ SUBSYSTEM_DEF(dbcore)
|
||||
/datum/controller/subsystem/dbcore/proc/SetRoundID()
|
||||
if(!Connect())
|
||||
return
|
||||
var/datum/DBQuery/query_round_initialize = SSdbcore.NewQuery("INSERT INTO [format_table_name("round")] (initialize_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]')")
|
||||
var/datum/DBQuery/query_round_initialize = SSdbcore.NewQuery(
|
||||
"INSERT INTO [format_table_name("round")] (initialize_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(:internet_address), :port)",
|
||||
list("internet_address" = world.internet_address || "0", "port" = "[world.port]")
|
||||
)
|
||||
query_round_initialize.Execute(async = FALSE)
|
||||
GLOB.round_id = "[query_round_initialize.last_insert_id]"
|
||||
var/datum/DBQuery/query_fix_connections = SSdbcore.NewQuery("UPDATE [format_table_name("connection_log")] SET 'left' = NOW() WHERE 'left' IS NULL AND round_id = :id", list("id" = text2num(GLOB.round_id) - 1))
|
||||
query_fix_connections.Execute()
|
||||
qdel(query_fix_connections)
|
||||
qdel(query_round_initialize)
|
||||
var/datum/DBQuery/query_round_last_id = SSdbcore.NewQuery("SELECT LAST_INSERT_ID()")
|
||||
query_round_last_id.Execute(async = FALSE)
|
||||
if(query_round_last_id.NextRow(async = FALSE))
|
||||
GLOB.round_id = query_round_last_id.item[1]
|
||||
var/datum/DBQuery/query_fix_connections = SSdbcore.NewQuery("UPDATE [format_table_name("connection_log")] SET 'left' = NOW() WHERE 'left' IS NULL AND round_id = [text2num(GLOB.round_id) - 1]")
|
||||
query_fix_connections.Execute()
|
||||
qdel(query_fix_connections)
|
||||
qdel(query_round_last_id)
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/SetRoundStart()
|
||||
if(!Connect())
|
||||
return
|
||||
var/datum/DBQuery/query_round_start = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET start_datetime = Now() WHERE id = [GLOB.round_id]")
|
||||
var/datum/DBQuery/query_round_start = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("round")] SET start_datetime = Now() WHERE id = :round_id",
|
||||
list("round_id" = GLOB.round_id)
|
||||
)
|
||||
query_round_start.Execute()
|
||||
qdel(query_round_start)
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/SetRoundEnd()
|
||||
if(!Connect())
|
||||
return
|
||||
var/sql_station_name = sanitizeSQL(station_name())
|
||||
var/datum/DBQuery/query_round_end = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET end_datetime = Now(), game_mode_result = '[sanitizeSQL(SSticker.mode_result)]', station_name = '[sql_station_name]' WHERE id = [GLOB.round_id]")
|
||||
var/datum/DBQuery/query_round_end = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("round")] SET end_datetime = Now(), game_mode_result = :game_mode_result, station_name = :station_name WHERE id = :round_id",
|
||||
list("game_mode_result" = SSticker.mode_result, "station_name" = station_name(), "round_id" = GLOB.round_id)
|
||||
)
|
||||
query_round_end.Execute()
|
||||
qdel(query_round_end)
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/Disconnect()
|
||||
failed_connections = 0
|
||||
QDEL_NULL(connectOperation)
|
||||
QDEL_NULL(connection)
|
||||
if (connection)
|
||||
rustg_sql_disconnect_pool(connection)
|
||||
connection = null
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/IsConnected()
|
||||
if(!CONFIG_GET(flag/sql_enabled))
|
||||
if (!CONFIG_GET(flag/sql_enabled))
|
||||
return FALSE
|
||||
//block until any connect operations finish
|
||||
var/datum/BSQL_Connection/_connection = connection
|
||||
var/datum/BSQL_Operation/op = connectOperation
|
||||
UNTIL(QDELETED(_connection) || op.IsComplete())
|
||||
return !QDELETED(connection) && !op.GetError()
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/Quote(str)
|
||||
if(connection)
|
||||
return connection.Quote(str)
|
||||
if (!connection)
|
||||
return FALSE
|
||||
return json_decode(rustg_sql_connected(connection))["status"] == "online"
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/ErrorMsg()
|
||||
if(!CONFIG_GET(flag/sql_enabled))
|
||||
@@ -178,12 +179,12 @@ SUBSYSTEM_DEF(dbcore)
|
||||
/datum/controller/subsystem/dbcore/proc/ReportError(error)
|
||||
last_error = error
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/NewQuery(sql_query)
|
||||
/datum/controller/subsystem/dbcore/proc/NewQuery(sql_query, arguments)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
log_admin_private("ERROR: Advanced admin proc call led to sql query: [sql_query]. Query has been blocked")
|
||||
message_admins("ERROR: Advanced admin proc call led to sql query. Query has been blocked")
|
||||
return FALSE
|
||||
return new /datum/DBQuery(sql_query, connection)
|
||||
return new /datum/DBQuery(connection, sql_query, arguments)
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/QuerySelect(list/querys, warn = FALSE, qdel = FALSE)
|
||||
if (!islist(querys))
|
||||
@@ -218,55 +219,60 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
|
||||
It was included because it is still supported in mariadb.
|
||||
It does not work with duplicate_key and the mysql server ignores it in those cases
|
||||
*/
|
||||
/datum/controller/subsystem/dbcore/proc/MassInsert(table, list/rows, duplicate_key = FALSE, ignore_errors = FALSE, delayed = FALSE, warn = FALSE, async = TRUE)
|
||||
/datum/controller/subsystem/dbcore/proc/MassInsert(table, list/rows, duplicate_key = FALSE, ignore_errors = FALSE, delayed = FALSE, warn = FALSE, async = TRUE, special_columns = null)
|
||||
if (!table || !rows || !istype(rows))
|
||||
return
|
||||
|
||||
// Prepare column list
|
||||
var/list/columns = list()
|
||||
var/list/sorted_rows = list()
|
||||
|
||||
var/list/has_question_mark = list()
|
||||
for (var/list/row in rows)
|
||||
var/list/sorted_row = list()
|
||||
sorted_row.len = columns.len
|
||||
for (var/column in row)
|
||||
var/idx = columns[column]
|
||||
if (!idx)
|
||||
idx = columns.len + 1
|
||||
columns[column] = idx
|
||||
sorted_row.len = columns.len
|
||||
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], "?")
|
||||
|
||||
sorted_row[idx] = row[column]
|
||||
sorted_rows[++sorted_rows.len] = sorted_row
|
||||
// Prepare SQL query full of placeholders
|
||||
var/list/query_parts = list("INSERT")
|
||||
if (delayed)
|
||||
query_parts += " DELAYED"
|
||||
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])"
|
||||
duplicate_key = "ON DUPLICATE KEY UPDATE [column_list.Join(", ")]\n"
|
||||
else if (duplicate_key == FALSE)
|
||||
duplicate_key = null
|
||||
query_parts += "\nON DUPLICATE KEY UPDATE [column_list.Join(", ")]"
|
||||
else if (duplicate_key != FALSE)
|
||||
query_parts += duplicate_key
|
||||
|
||||
if (ignore_errors)
|
||||
ignore_errors = " IGNORE"
|
||||
else
|
||||
ignore_errors = null
|
||||
|
||||
if (delayed)
|
||||
delayed = " DELAYED"
|
||||
else
|
||||
delayed = null
|
||||
|
||||
var/list/sqlrowlist = list()
|
||||
var/len = columns.len
|
||||
for (var/list/row in sorted_rows)
|
||||
if (length(row) != len)
|
||||
row.len = len
|
||||
for (var/value in row)
|
||||
if (value == null)
|
||||
value = "NULL"
|
||||
sqlrowlist += "([row.Join(", ")])"
|
||||
|
||||
sqlrowlist = " [sqlrowlist.Join(",\n ")]"
|
||||
var/datum/DBQuery/Query = NewQuery("INSERT[delayed][ignore_errors] INTO [table]\n([columns.Join(", ")])\nVALUES\n[sqlrowlist]\n[duplicate_key]")
|
||||
var/datum/DBQuery/Query = NewQuery(query_parts.Join(), arguments)
|
||||
if (warn)
|
||||
. = Query.warn_execute(async)
|
||||
else
|
||||
@@ -274,24 +280,33 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
|
||||
qdel(Query)
|
||||
|
||||
/datum/DBQuery
|
||||
var/sql // The sql query being executed.
|
||||
var/list/item //list of data values populated by NextRow()
|
||||
// Inputs
|
||||
var/connection
|
||||
var/sql
|
||||
var/arguments
|
||||
|
||||
// Status information
|
||||
var/in_progress
|
||||
var/last_error
|
||||
var/last_activity
|
||||
var/last_activity_time
|
||||
|
||||
var/last_error
|
||||
var/skip_next_is_complete
|
||||
var/in_progress
|
||||
var/datum/BSQL_Connection/connection
|
||||
var/datum/BSQL_Operation/Query/query
|
||||
// Output
|
||||
var/list/list/rows
|
||||
var/next_row_to_take = 1
|
||||
var/affected
|
||||
var/last_insert_id
|
||||
|
||||
/datum/DBQuery/New(sql_query, datum/BSQL_Connection/connection)
|
||||
var/list/item //list of data values populated by NextRow()
|
||||
|
||||
/datum/DBQuery/New(connection, sql, arguments)
|
||||
SSdbcore.active_queries[src] = TRUE
|
||||
Activity("Created")
|
||||
item = list()
|
||||
|
||||
src.connection = connection
|
||||
sql = sql_query
|
||||
src.sql = sql
|
||||
src.arguments = arguments
|
||||
|
||||
/datum/DBQuery/Destroy()
|
||||
Close()
|
||||
@@ -302,12 +317,6 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
|
||||
//fuck off kevinz
|
||||
return FALSE
|
||||
|
||||
/datum/DBQuery/proc/SetQuery(new_sql)
|
||||
if(in_progress)
|
||||
CRASH("Attempted to set new sql while waiting on active query")
|
||||
Close()
|
||||
sql = new_sql
|
||||
|
||||
/datum/DBQuery/proc/Activity(activity)
|
||||
last_activity = activity
|
||||
last_activity_time = world.time
|
||||
@@ -322,30 +331,18 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
|
||||
if(in_progress)
|
||||
CRASH("Attempted to start a new query while waiting on the old one")
|
||||
|
||||
if(QDELETED(connection))
|
||||
if(!SSdbcore.IsConnected())
|
||||
last_error = "No connection!"
|
||||
return FALSE
|
||||
|
||||
var/start_time
|
||||
var/timed_out
|
||||
if(!async)
|
||||
start_time = REALTIMEOFDAY
|
||||
Close()
|
||||
timed_out = run_query(async)
|
||||
if(query.GetErrorCode() == 2006) //2006 is the return code for "MySQL server has gone away" time-out error, meaning the connection has been lost to the server (if it's still alive)
|
||||
log_sql("Executing query encountered returned a lost database connection (2006).")
|
||||
SSdbcore.Disconnect()
|
||||
if(SSdbcore.Connect()) //connection was restablished, reattempt the query
|
||||
log_sql("Connection restablished")
|
||||
timed_out = run_query(async)
|
||||
else
|
||||
log_sql("Executing query failed to restablish database connection.")
|
||||
skip_next_is_complete = TRUE
|
||||
var/error = QDELETED(query) ? "Query object deleted!" : query.GetError()
|
||||
last_error = error
|
||||
. = !error
|
||||
. = run_query(async)
|
||||
var/timed_out = !. && findtext(last_error, "Operation timed out")
|
||||
if(!. && log_error)
|
||||
log_sql("[error] | Query used: [sql]")
|
||||
log_sql("[last_error] | Query used: [sql]")
|
||||
if(!async && timed_out)
|
||||
log_query_debug("Query execution started at [start_time]")
|
||||
log_query_debug("Query execution ended at [REALTIMEOFDAY]")
|
||||
@@ -354,52 +351,50 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
|
||||
slow_query_check()
|
||||
|
||||
/datum/DBQuery/proc/run_query(async)
|
||||
query = connection.BeginQuery(sql)
|
||||
if(!async)
|
||||
. = !query.WaitForCompletion()
|
||||
else
|
||||
var/job_result_str
|
||||
|
||||
if (async)
|
||||
var/job_id = rustg_sql_query_async(connection, sql, json_encode(arguments))
|
||||
in_progress = TRUE
|
||||
UNTIL(query.IsComplete())
|
||||
UNTIL((job_result_str = rustg_sql_check_query(job_id)) != RUSTG_JOB_NO_RESULTS_YET)
|
||||
in_progress = FALSE
|
||||
|
||||
if (job_result_str == RUSTG_JOB_ERROR)
|
||||
last_error = job_result_str
|
||||
return FALSE
|
||||
else
|
||||
job_result_str = rustg_sql_query_blocking(connection, sql, json_encode(arguments))
|
||||
|
||||
var/result = json_decode(job_result_str)
|
||||
switch (result["status"])
|
||||
if ("ok")
|
||||
rows = result["rows"]
|
||||
affected = result["affected"]
|
||||
last_insert_id = result["last_insert_id"]
|
||||
return TRUE
|
||||
if ("err")
|
||||
last_error = result["data"]
|
||||
return FALSE
|
||||
if ("offline")
|
||||
last_error = "offline"
|
||||
return FALSE
|
||||
|
||||
/datum/DBQuery/proc/slow_query_check()
|
||||
message_admins("HEY! A database query timed out. Did the server just hang? <a href='?_src_=holder;[HrefToken()];slowquery=yes'>\[YES\]</a>|<a href='?_src_=holder;[HrefToken()];slowquery=no'>\[NO\]</a>")
|
||||
|
||||
/datum/DBQuery/proc/NextRow(async = TRUE)
|
||||
Activity("NextRow")
|
||||
UNTIL(!in_progress)
|
||||
if(!skip_next_is_complete)
|
||||
if(!async)
|
||||
query.WaitForCompletion()
|
||||
else
|
||||
in_progress = TRUE
|
||||
UNTIL(query.IsComplete())
|
||||
in_progress = FALSE
|
||||
|
||||
if (rows && next_row_to_take <= rows.len)
|
||||
item = rows[next_row_to_take]
|
||||
next_row_to_take++
|
||||
return !!item
|
||||
else
|
||||
skip_next_is_complete = FALSE
|
||||
|
||||
last_error = query.GetError()
|
||||
var/list/results = query.CurrentRow()
|
||||
. = results != null
|
||||
|
||||
item.Cut()
|
||||
//populate item array
|
||||
for(var/I in results)
|
||||
item += results[I]
|
||||
return FALSE
|
||||
|
||||
/datum/DBQuery/proc/ErrorMsg()
|
||||
return last_error
|
||||
|
||||
/datum/DBQuery/proc/Close()
|
||||
item.Cut()
|
||||
QDEL_NULL(query)
|
||||
|
||||
/world/BSQL_Debug(message)
|
||||
if(!CONFIG_GET(flag/bsql_debug))
|
||||
return
|
||||
|
||||
//strip sensitive stuff
|
||||
if(findtext(message, ": OpenConnection("))
|
||||
message = "OpenConnection CENSORED"
|
||||
|
||||
log_sql("BSQL_DEBUG: [message]")
|
||||
rows = null
|
||||
item = null
|
||||
@@ -19,7 +19,10 @@ SUBSYSTEM_DEF(discord)
|
||||
|
||||
// Returns ID from ckey
|
||||
/datum/controller/subsystem/discord/proc/lookup_id(lookup_ckey)
|
||||
var/datum/DBQuery/query_get_discord_id = SSdbcore.NewQuery("SELECT discord_id FROM [format_table_name("player")] WHERE ckey = '[sanitizeSQL(lookup_ckey)]'")
|
||||
var/datum/DBQuery/query_get_discord_id = SSdbcore.NewQuery(
|
||||
"SELECT discord_id FROM [format_table_name("player")] WHERE ckey = :ckey",
|
||||
list("ckey" = lookup_ckey)
|
||||
)
|
||||
if(!query_get_discord_id.Execute())
|
||||
qdel(query_get_discord_id)
|
||||
return
|
||||
@@ -29,7 +32,10 @@ SUBSYSTEM_DEF(discord)
|
||||
|
||||
// Returns ckey from ID
|
||||
/datum/controller/subsystem/discord/proc/lookup_ckey(lookup_id)
|
||||
var/datum/DBQuery/query_get_discord_ckey = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE discord_id = '[sanitizeSQL(lookup_id)]'")
|
||||
var/datum/DBQuery/query_get_discord_ckey = SSdbcore.NewQuery(
|
||||
"SELECT ckey FROM [format_table_name("player")] WHERE discord_id = :discord_id",
|
||||
list("discord_id" = lookup_id)
|
||||
)
|
||||
if(!query_get_discord_ckey.Execute())
|
||||
qdel(query_get_discord_ckey)
|
||||
return
|
||||
@@ -39,14 +45,20 @@ SUBSYSTEM_DEF(discord)
|
||||
|
||||
// Finalises link
|
||||
/datum/controller/subsystem/discord/proc/link_account(ckey)
|
||||
var/datum/DBQuery/link_account = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET discord_id = '[sanitizeSQL(account_link_cache[ckey])]' WHERE ckey = '[sanitizeSQL(ckey)]'")
|
||||
var/datum/DBQuery/link_account = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("player")] SET discord_id = :discord_id WHERE ckey = :ckey",
|
||||
list("discord_id" = account_link_cache[ckey], "ckey" = ckey)
|
||||
)
|
||||
link_account.Execute()
|
||||
qdel(link_account)
|
||||
account_link_cache -= ckey
|
||||
|
||||
// Unlink account (Admin verb used)
|
||||
/datum/controller/subsystem/discord/proc/unlink_account(ckey)
|
||||
var/datum/DBQuery/unlink_account = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET discord_id = NULL WHERE ckey = '[sanitizeSQL(ckey)]'")
|
||||
var/datum/DBQuery/unlink_account = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("player")] SET discord_id = NULL WHERE ckey = :ckey",
|
||||
list("ckey" = ckey)
|
||||
)
|
||||
unlink_account.Execute()
|
||||
qdel(unlink_account)
|
||||
|
||||
|
||||
@@ -264,7 +264,9 @@ SUBSYSTEM_DEF(mapping)
|
||||
LoadGroup(FailedZs, "Station", config.map_path, config.map_file, config.traits, ZTRAITS_STATION)
|
||||
|
||||
if(SSdbcore.Connect())
|
||||
var/datum/DBQuery/query_round_map_name = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET map_name = '[config.map_name]' WHERE id = [GLOB.round_id]")
|
||||
var/datum/DBQuery/query_round_map_name = SSdbcore.NewQuery({"
|
||||
UPDATE [format_table_name("round")] SET map_name = :map_name WHERE id = :round_id
|
||||
"}, list("map_name" = config.map_name, "round_id" = GLOB.round_id))
|
||||
query_round_map_name.Execute()
|
||||
qdel(query_round_map_name)
|
||||
|
||||
|
||||
@@ -150,7 +150,10 @@ SUBSYSTEM_DEF(stickyban)
|
||||
if (!ban["message"])
|
||||
ban["message"] = "Evasion"
|
||||
|
||||
var/datum/DBQuery/query_create_stickyban = SSdbcore.NewQuery("INSERT IGNORE INTO [format_table_name("stickyban")] (ckey, reason, banning_admin) VALUES ('[sanitizeSQL(ckey)]', '[sanitizeSQL(ban["message"])]', '[sanitizeSQL(ban["admin"])]')")
|
||||
var/datum/DBQuery/query_create_stickyban = SSdbcore.NewQuery(
|
||||
"INSERT IGNORE INTO [format_table_name("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
|
||||
@@ -164,8 +167,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
|
||||
|
||||
@@ -173,8 +176,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
|
||||
|
||||
@@ -182,26 +185,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))
|
||||
SSdbcore.MassInsert(format_table_name("stickyban_matched_ckey"), sqlckeys, FALSE, TRUE)
|
||||
SSdbcore.MassInsert(format_table_name("stickyban_matched_ckey"), sqlckeys, ignore_errors = TRUE)
|
||||
|
||||
if (length(sqlcids))
|
||||
SSdbcore.MassInsert(format_table_name("stickyban_matched_cid"), sqlcids, FALSE, TRUE)
|
||||
SSdbcore.MassInsert(format_table_name("stickyban_matched_cid"), sqlcids, ignore_errors = TRUE)
|
||||
|
||||
if (length(sqlips))
|
||||
SSdbcore.MassInsert(format_table_name("stickyban_matched_ip"), sqlips, FALSE, TRUE)
|
||||
SSdbcore.MassInsert(format_table_name("stickyban_matched_ip"), sqlips, ignore_errors = TRUE)
|
||||
|
||||
|
||||
return TRUE
|
||||
|
||||
Reference in New Issue
Block a user