diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index ce3e42e441f..afbf53faf13 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -112,7 +112,8 @@ var/list/admin_verbs_debug = list(
/client/proc/cmd_debug_del_all,
/client/proc/restart_controller,
/client/proc/enable_debug_verbs,
- /client/proc/callproc
+ /client/proc/callproc,
+ /client/proc/SDQL2_query
)
var/list/admin_verbs_possess = list(
/proc/possess,
diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm
index 505482d4567..70af98fa0dd 100644
--- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm
+++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm
@@ -1,4 +1,5 @@
// Code taken from /bay/station.
+// Modified to allow consequtive querys in one invocation, terminated with ";"
// Examples
/*
@@ -10,6 +11,8 @@
UPDATE /obj/machinery/light IN world SET color = "#0F0" WHERE icon_state == "tube1"
-- Will delete all pickaxes. "IN world" is not required.
DELETE /obj/item/weapon/pickaxe
+ -- Will flicker the lights once, then turn all mobs green. The semicolon is important to separate the consecutive querys, but is not required for standard one-query use
+ CALL flicker(1) ON /obj/machinery/light; UPDATE /mob SET color = "#00cc00"
--You can use operators other than ==, such as >, <=, != and etc..
@@ -31,123 +34,153 @@
if(!query_list || query_list.len < 1)
return
- var/list/query_tree = SDQL_parse(query_list)
+ var/list/querys = SDQL_parse(query_list)
- if(query_tree.len < 1)
+ if(!querys || querys.len < 1)
return
- var/list/from_objs = list()
- var/list/select_types = list()
-
- switch(query_tree[1])
- if("explain")
- SDQL_testout(query_tree["explain"])
- return
-
- if("call")
- if("on" in query_tree)
- select_types = query_tree["on"]
- else
- return
-
- if("select", "delete", "update")
- select_types = query_tree[query_tree[1]]
-
- from_objs = SDQL_from_objs(query_tree["from"])
-
- var/list/objs = list()
-
- for(var/type in select_types)
- var/char = copytext(type, 1, 2)
-
- if(char == "/" || char == "*")
- for(var/from in from_objs)
- objs += SDQL_get_all(type, from)
-
- else if(char == "'" || char == "\"")
- objs += locate(copytext(type, 2, length(type)))
-
- if("where" in query_tree)
- var/objs_temp = objs
- objs = list()
- for(var/datum/d in objs_temp)
- if(SDQL_expression(d, query_tree["where"]))
- objs += d
var/query_log = "[usr] executed SDQL query: \"[query_text]\"."
world.log << query_log
message_admins(query_log)
log_game(query_log)
- switch(query_tree[1])
- if("call")
- var/list/call_list = query_tree["call"]
- var/list/args_list = query_tree["args"]
+ for(var/list/query_tree in querys)
+ var/list/from_objs = list()
+ var/list/select_types = list()
- for(var/datum/d in objs)
- for(var/v in call_list)
- // To stop any procs which sleep from executing slowly.
- if(d)
- if(hascall(d, v))
- spawn() call(d, v)(arglist(args_list)) // Spawn in case the function sleeps.
+ switch(query_tree[1])
+ if("explain")
+ SDQL_testout(query_tree["explain"])
+ return
- if("delete")
- for(var/datum/d in objs)
- del d
+ if("call")
+ if("on" in query_tree)
+ select_types = query_tree["on"]
+ else
+ return
- if("select")
- var/text = ""
- for(var/datum/t in objs)
- text += "\ref[t]"
- if(istype(t, /atom))
- var/atom/a = t
+ if("select", "delete", "update")
+ select_types = query_tree[query_tree[1]]
- if(a.x)
- text += ": [t] at ([a.x], [a.y], [a.z])
"
+ from_objs = SDQL_from_objs(query_tree["from"])
- else if(a.loc && a.loc.x)
- text += ": [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])
"
+ var/list/objs = list()
+
+ for(var/type in select_types)
+ var/char = copytext(type, 1, 2)
+
+ if(char == "/" || char == "*")
+ for(var/from in from_objs)
+ objs += SDQL_get_all(type, from)
+
+ else if(char == "'" || char == "\"")
+ objs += locate(copytext(type, 2, length(type)))
+
+ if("where" in query_tree)
+ var/objs_temp = objs
+ objs = list()
+ for(var/datum/d in objs_temp)
+ if(SDQL_expression(d, query_tree["where"]))
+ objs += d
+
+ switch(query_tree[1])
+ if("call")
+ var/list/call_list = query_tree["call"]
+ var/list/args_list = query_tree["args"]
+
+ for(var/datum/d in objs)
+ for(var/v in call_list)
+ // To stop any procs which sleep from executing slowly.
+ if(d)
+ if(hascall(d, v))
+ spawn() call(d, v)(arglist(args_list)) // Spawn in case the function sleeps.
+
+ if("delete")
+ for(var/datum/d in objs)
+ del d
+
+ if("select")
+ var/text = ""
+ for(var/datum/t in objs)
+ text += "\ref[t]"
+ if(istype(t, /atom))
+ var/atom/a = t
+
+ if(a.x)
+ text += ": [t] at ([a.x], [a.y], [a.z])
"
+
+ else if(a.loc && a.loc.x)
+ text += ": [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])
"
+
+ else
+ text += ": [t]
"
else
text += ": [t]
"
- else
- text += ": [t]
"
+ usr << browse(text, "window=SDQL-result")
- usr << browse(text, "window=SDQL-result")
+ if("update")
+ if("set" in query_tree)
+ var/list/set_list = query_tree["set"]
+ for(var/datum/d in objs)
+ var/list/vals = list()
+ for(var/v in set_list)
+ if(v in d.vars)
+ vals += v
+ vals[v] = SDQL_expression(d, set_list[v])
- if("update")
- if("set" in query_tree)
- var/list/set_list = query_tree["set"]
- for(var/datum/d in objs)
- var/list/vals = list()
- for(var/v in set_list)
- if(v in d.vars)
- vals += v
- vals[v] = SDQL_expression(d, set_list[v])
+ if(istype(d, /turf))
+ for(var/v in vals)
+ if(v == "x" || v == "y" || v == "z")
+ continue
- if(istype(d, /turf))
- for(var/v in vals)
- if(v == "x" || v == "y" || v == "z")
- continue
+ d.vars[v] = vals[v]
- d.vars[v] = vals[v]
-
- else
- for(var/v in vals)
- d.vars[v] = vals[v]
+ else
+ for(var/v in vals)
+ d.vars[v] = vals[v]
/proc/SDQL_parse(list/query_list)
- var/datum/SDQL_parser/parser = new(query_list)
- var/list/query_tree = parser.parse()
+ var/datum/SDQL_parser/parser = new()
+ var/list/querys = list()
+ var/list/query_tree = list()
+ var/pos = 1
+ var/querys_pos = 1
+ var/do_parse = 0
+
+ for(var/val in query_list)
+ if(val == ";")
+ do_parse = 1
+ else if(pos >= query_list.len)
+ query_tree += val
+ do_parse = 1
+
+ if(do_parse)
+ parser.query = query_tree
+ var/list/parsed_tree
+ parsed_tree = parser.parse()
+ if(parsed_tree.len > 0)
+ querys.len = querys_pos
+ querys[querys_pos] = parsed_tree
+ querys_pos++
+ else //There was an error so don't run anything, and tell the user which query has errored.
+ usr << "Parsing error on [querys_pos]\th query. Nothing was executed."
+ return list()
+ query_tree = list()
+ do_parse = 0
+ else
+ query_tree += val
+ pos++
del(parser)
- return query_tree
+ return querys
@@ -350,7 +383,7 @@
/proc/SDQL2_tokenize(query_text)
var/list/whitespace = list(" ", "\n", "\t")
- var/list/single = list("(", ")", ",", "+", "-", ".")
+ var/list/single = list("(", ")", ",", "+", "-", ".", ";")
var/list/multi = list(
"=" = list("", "="),
"<" = list("", "=", ">"),
@@ -451,4 +484,4 @@
if(word != "")
query_list += word
- return query_list
\ No newline at end of file
+ return query_list
diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm
index 5eee72c78c3..775210d6107 100644
--- a/code/modules/admin/verbs/mapping.dm
+++ b/code/modules/admin/verbs/mapping.dm
@@ -145,7 +145,6 @@ var/intercom_range_display_status = 0
src.verbs += /client/proc/disable_communication
src.verbs += /client/proc/print_pointers
src.verbs += /client/proc/count_movable_instances
- src.verbs += /client/proc/SDQL2_query
src.verbs += /client/proc/cmd_display_del_log
//src.verbs += /client/proc/cmd_admin_rejuvenate