Async SQL + SSdbcore (#15007)

* Initial Commit - Async SQL

* First batch of queries

* More progress

* Nukes DB Polls

* More work

* oops

* One push

* Notes work now

* Ok these work

* Watchlist done

* Async Bans!

* Async Permissions

* Async client procs

* I officially hate preference datums

* Also these

* Async Custom Items

* Async Karma

* Async Library

* Async TOS

* Cleans out the old SQL code

* CI Sanity

* Apparently MySQL doesnt support this

* What about this

* Maybe this

* Review pass 1

* This too

* Fixes job ban loading

* Fix undeleted queries

* Prevents sensitive queries being logged

* Documentation + tweaks

* Adds a verb to force reconnect the DB

* More review tweaks

* Farie tweaks

* Fixes this
This commit is contained in:
AffectedArc07
2020-12-16 15:46:25 -05:00
committed by GitHub
parent e003d552b0
commit 2bad70717c
55 changed files with 2251 additions and 2445 deletions
+37 -20
View File
@@ -31,48 +31,65 @@
/obj/machinery/computer/library/proc/get_page(var/page_num)
var/searchquery = ""
var/where = 0
var/list/sql_params = list()
if(query)
if(query.title && query.title != "")
searchquery += " WHERE title LIKE '%[sanitizeSQL(query.title)]%'"
searchquery += " WHERE title LIKE :title"
sql_params["title"] = "%[query.title]%"
where = 1
if(query.author && query.author != "")
searchquery += " [!where ? "WHERE" : "AND"] author LIKE '%[sanitizeSQL(query.author)]%'"
searchquery += " [!where ? "WHERE" : "AND"] author LIKE :author"
sql_params["author"] = "%[query.author]%"
where = 1
if(query.category && query.category != "")
searchquery += " [!where ? "WHERE" : "AND"] category LIKE '%[sanitizeSQL(query.category)]%'"
searchquery += " [!where ? "WHERE" : "AND"] category LIKE :cat"
sql_params["cat"] = "%[query.category]%"
if(query.category == "Fiction")
searchquery += " AND category NOT LIKE '%Non-Fiction%'"
where = 1
// This one doesnt take player input directly, so it doesnt require params
searchquery += " [!where ? "WHERE" : "AND"] flagged < [MAX_BOOK_FLAGS]"
var/sql = "SELECT id, author, title, category, ckey, flagged FROM [format_table_name("library")] [searchquery] LIMIT [(page_num - 1) * LIBRARY_BOOKS_PER_PAGE], [LIBRARY_BOOKS_PER_PAGE]"
// This does though
var/sql = "SELECT id, author, title, category, ckey, flagged FROM [format_table_name("library")] [searchquery] LIMIT :lowerlimit, :upperlimit"
sql_params["lowerlimit"] = text2num((page_num - 1) * LIBRARY_BOOKS_PER_PAGE)
sql_params["upperlimit"] = LIBRARY_BOOKS_PER_PAGE
// Pagination
var/DBQuery/_query = GLOB.dbcon.NewQuery(sql)
_query.Execute()
if(_query.ErrorMsg())
log_world(_query.ErrorMsg())
var/datum/db_query/select_query = SSdbcore.NewQuery(sql, sql_params)
if(!select_query.warn_execute())
qdel(select_query)
return
var/list/results = list()
while(_query.NextRow())
while(select_query.NextRow())
var/datum/cachedbook/CB = new()
CB.LoadFromRow(list(
"id" =_query.item[1],
"author" =_query.item[2],
"title" =_query.item[3],
"category"=_query.item[4],
"ckey" =_query.item[5],
"flagged" =text2num(_query.item[6])
"id" =select_query.item[1],
"author" =select_query.item[2],
"title" =select_query.item[3],
"category"=select_query.item[4],
"ckey" =select_query.item[5],
"flagged" =text2num(select_query.item[6])
))
results += CB
qdel(select_query)
return results
/obj/machinery/computer/library/proc/get_num_results()
var/sql = "SELECT COUNT(*) FROM [format_table_name("library")]"
var/sql = "SELECT COUNT(id) FROM [format_table_name("library")]"
var/DBQuery/_query = GLOB.dbcon.NewQuery(sql)
_query.Execute()
while(_query.NextRow())
return text2num(_query.item[1])
var/datum/db_query/count_query = SSdbcore.NewQuery(sql)
if(!count_query.warn_execute())
qdel(count_query)
return
while(count_query.NextRow())
var/value = text2num(count_query.item[1])
qdel(count_query)
return value
qdel(count_query)
return 0
/obj/machinery/computer/library/proc/get_pagelist()
+39 -29
View File
@@ -91,7 +91,7 @@
<A href='?src=[UID()];switchscreen=0'>(Return to main menu)</A><BR>"}
if(4)
dat += "<h3>External Archive</h3>"
if(!GLOB.dbcon.IsConnected())
if(!SSdbcore.IsConnected())
dat += "<font color=red><b>ERROR</b>: Unable to contact External Archive. Please contact your system administrator for assistance.</font>"
else
num_results = src.get_num_results()
@@ -262,11 +262,13 @@
var/datum/cachedbook/target = getBookByID(href_list["del"]) // Sanitized in getBookByID
var/ans = alert(usr, "Are you sure you wish to delete \"[target.title]\", by [target.author]? This cannot be undone.", "Library System", "Yes", "No")
if(ans=="Yes")
var/DBQuery/query = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("library")] WHERE id=[target.id]")
var/response = query.Execute()
if(!response)
to_chat(usr, query.ErrorMsg())
var/datum/db_query/query = SSdbcore.NewQuery("DELETE FROM [format_table_name("library")] WHERE id=:id", list(
"id" = text2num(target.id)
))
if(!query.warn_execute())
qdel(query)
return
qdel(query)
log_admin("LIBRARY: [key_name(usr)] has deleted \"[target.title]\", by [target.author] ([target.ckey])!")
message_admins("[key_name_admin(usr)] has deleted \"[target.title]\", by [target.author] ([target.ckey])!")
src.updateUsrDialog()
@@ -278,22 +280,25 @@
var/tckey = ckey(href_list["delbyckey"])
var/ans = alert(usr,"Are you sure you wish to delete all books by [tckey]? This cannot be undone.", "Library System", "Yes", "No")
if(ans=="Yes")
var/DBQuery/query = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("library")] WHERE ckey='[sanitizeSQL(tckey)]'")
var/response = query.Execute()
if(!response)
to_chat(usr, query.ErrorMsg())
var/datum/db_query/query = SSdbcore.NewQuery("DELETE FROM [format_table_name("library")] WHERE ckey=:ckey", list(
"ckey" = tckey
))
if(!query.warn_execute())
qdel(query)
return
var/affected=query.RowsAffected()
if(affected==0)
if(query.affected == 0)
to_chat(usr, "<span class='danger'>Unable to find any matching rows.</span>")
qdel(query)
return
log_admin("LIBRARY: [key_name(usr)] has deleted [affected] books written by [tckey]!")
message_admins("[key_name_admin(usr)] has deleted [affected] books written by [tckey]!")
qdel(query)
log_admin("LIBRARY: [key_name(usr)] has deleted [query.affected] books written by [tckey]!")
message_admins("[key_name_admin(usr)] has deleted [query.affected] books written by [tckey]!")
src.updateUsrDialog()
return
if(href_list["flag"])
if(!GLOB.dbcon.IsConnected())
if(!SSdbcore.IsConnected())
alert("Connection to Archive has been severed. Aborting.")
return
var/id = href_list["flag"]
@@ -378,21 +383,26 @@
if(scanner.cache)
var/choice = input("Are you certain you wish to upload this title to the Archive?") in list("Confirm", "Abort")
if(choice == "Confirm")
establish_db_connection()
if(!GLOB.dbcon.IsConnected())
if(!SSdbcore.IsConnected())
alert("Connection to Archive has been severed. Aborting.")
else
var/sqltitle = sanitizeSQL(scanner.cache.name)
var/sqlauthor = sanitizeSQL(scanner.cache.author)
var/sqlcontent = sanitizeSQL(scanner.cache.dat)
var/sqlcategory = sanitizeSQL(upload_category)
var/DBQuery/query = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("library")] (author, title, content, category, ckey, flagged) VALUES ('[sqlauthor]', '[sqltitle]', '[sqlcontent]', '[sqlcategory]', '[ckey(usr.key)]', 0)")
var/response = query.Execute()
if(!response)
to_chat(usr, query.ErrorMsg())
else
log_admin("[usr.name]/[usr.key] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] characters in length")
message_admins("[key_name_admin(usr)] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] characters in length")
var/datum/db_query/query = SSdbcore.NewQuery({"
INSERT INTO [format_table_name("library")] (author, title, content, category, ckey, flagged)
VALUES (:author, :title, :content, :category, :ckey, 0)"}, list(
"author" = scanner.cache.author,
"title" = scanner.cache.name,
"content" = scanner.cache.dat,
"category" = upload_category,
"ckey" = usr.ckey
))
if(!query.warn_execute())
qdel(query)
return
qdel(query)
log_admin("[usr.name]/[usr.key] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] characters in length")
message_admins("[key_name_admin(usr)] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] characters in length")
if(href_list["id"])
if(href_list["id"]=="-1")
@@ -400,7 +410,7 @@
if(!href_list["id"])
return
if(!GLOB.dbcon.IsConnected())
if(!SSdbcore.IsConnected())
alert("Connection to Archive has been severed. Aborting.")
return
@@ -423,7 +433,7 @@
if(!href_list["manual"]) return
var/bookid = href_list["manual"]
if(!GLOB.dbcon.IsConnected())
if(!SSdbcore.IsConnected())
alert("Connection to Archive has been severed. Aborting.")
return
+2 -3
View File
@@ -26,8 +26,7 @@
<A href='?src=[UID()];setauthor=1'>Filter by Author: [query.author]</A><br />
<A href='?src=[UID()];search=1'>\[Start Search\]</A><br />"}
if(1)
establish_db_connection()
if(!GLOB.dbcon.IsConnected())
if(!SSdbcore.IsConnected())
dat += "<font color=red><b>ERROR</b>: Unable to contact External Archive. Please contact your system administrator for assistance.</font><br />"
else if(num_results == 0)
dat += "<em>No results found.</em>"
@@ -113,7 +112,7 @@
screenstate = 0
if(href_list["flag"])
if(!GLOB.dbcon.IsConnected())
if(!SSdbcore.IsConnected())
alert("Connection to Archive has been severed. Aborting.")
return
var/id = href_list["flag"]