diff --git a/fnl/conjure-spec/client/sql/stdio_spec.fnl b/fnl/conjure-spec/client/sql/stdio_spec.fnl new file mode 100644 index 00000000..ddfa9aa5 --- /dev/null +++ b/fnl/conjure-spec/client/sql/stdio_spec.fnl @@ -0,0 +1,40 @@ +(local {: describe : it} (require :plenary.busted)) +(local assert (require :luassert.assert)) +(local sql (require :conjure.client.sql.stdio)) + +(describe "conjure.client.sql.stdio" + (fn [] + (describe "prep-code" + (fn [] + (it "prepares sql code appropriately" + (fn [] + ;; Remove trailing comments from meta commands + ;; I may regret this when there's a meta command that takes double dash args... + (assert.same + "foo\n" + (sql.prep-code + {:code "foo -- bar" + :node {:type (fn [] :meta)}})) + + ;; Only works on the last line so we don't mangle code, hopefully + (assert.same + "foo -- bar\nsomething\n" + (sql.prep-code + {:code "foo -- bar\nsomething -- quuz" + :node {:type (fn [] :meta)}})) + + ;; If the last line has an extra blank line we do nothing, shouldn't really ever happen, but here's the behaviour anyway + (assert.same + "foo -- bar\nsomething -- quux\n\n" + (sql.prep-code + {:code "foo -- bar\nsomething -- quux\n" + :node {:type (fn [] :meta)}})) + + ;; If something is a statement it gets a semi colon on the end too + (assert.same + "foo;\n" + (sql.prep-code + {:code "foo -- bar" + :node {:type (fn [] :statement)}})) + + nil)))))) diff --git a/fnl/conjure/client/sql/stdio.fnl b/fnl/conjure/client/sql/stdio.fnl index d7730081..f9f9727d 100644 --- a/fnl/conjure/client/sql/stdio.fnl +++ b/fnl/conjure/client/sql/stdio.fnl @@ -3,6 +3,7 @@ (local str (autoload :conjure.aniseed.string)) (local client (autoload :conjure.client)) (local log (autoload :conjure.log)) +(local text (autoload :conjure.text)) (local stdio (autoload :conjure.remote.stdio-rt)) (local config (autoload :conjure.config)) (local mapping (autoload :conjure.mapping)) @@ -98,21 +99,31 @@ s [s])) +(fn prep-code [opts] + (let [node (a.get opts :node) + suffix (if (and node (= "statement" (node:type))) + ";\n" + "\n") + + ;; Removes trailing "-- ..." SQL comments from the code string + ;; These interfere with meta commands like .tables + ;; Only works on the last comment, intended for single lines + ;; This is because running it across multiple lines may mangle your source code + code (string.gsub opts.code "%s*%-%-[^\n]*$" "")] + + (.. code suffix))) + (fn eval-str [opts] (with-repl-or-warn (fn [repl] - (let [node (a.get opts :node) - suffix (if (and node (= "statement" (node:type))) - ";\n" - "\n")] - (repl.send - (.. opts.code suffix) - (fn [msgs] - (let [msgs (->list msgs)] - (when opts.on-result - (opts.on-result (str.join "\n" (remove-blank-lines (a.last msgs))))) - (a.run! display-result msgs))) - {:batch? false}))))) + (repl.send + (prep-code opts) + (fn [msgs] + (let [msgs (->list msgs)] + (when opts.on-result + (opts.on-result (str.join "\n" (remove-blank-lines (a.last msgs))))) + (a.run! display-result msgs))) + {:batch? false})))) ;;;;-------- End from client/fennel/stdio.fnl ------------------ (fn eval-file [opts] @@ -200,6 +211,7 @@ : get-form-modifier : comment-node? : ->list + : prep-code : eval-str : eval-file : interrupt diff --git a/lua/conjure-spec/client/sql/stdio_spec.lua b/lua/conjure-spec/client/sql/stdio_spec.lua new file mode 100644 index 00000000..3cfb6c1e --- /dev/null +++ b/lua/conjure-spec/client/sql/stdio_spec.lua @@ -0,0 +1,32 @@ +-- [nfnl] Compiled from fnl/conjure-spec/client/sql/stdio_spec.fnl by https://github.com/Olical/nfnl, do not edit. +local _local_1_ = require("plenary.busted") +local describe = _local_1_["describe"] +local it = _local_1_["it"] +local assert = require("luassert.assert") +local sql = require("conjure.client.sql.stdio") +local function _2_() + local function _3_() + local function _4_() + local function _5_() + return "meta" + end + assert.same("foo\n", sql["prep-code"]({code = "foo -- bar", node = {type = _5_}})) + local function _6_() + return "meta" + end + assert.same("foo -- bar\nsomething\n", sql["prep-code"]({code = "foo -- bar\nsomething -- quuz", node = {type = _6_}})) + local function _7_() + return "meta" + end + assert.same("foo -- bar\nsomething -- quux\n\n", sql["prep-code"]({code = "foo -- bar\nsomething -- quux\n", node = {type = _7_}})) + local function _8_() + return "statement" + end + assert.same("foo;\n", sql["prep-code"]({code = "foo -- bar", node = {type = _8_}})) + return nil + end + return it("prepares sql code appropriately", _4_) + end + return describe("prep-code", _3_) +end +return describe("conjure.client.sql.stdio", _2_) diff --git a/lua/conjure/client/sql/stdio.lua b/lua/conjure/client/sql/stdio.lua index ea089131..8d92021b 100644 --- a/lua/conjure/client/sql/stdio.lua +++ b/lua/conjure/client/sql/stdio.lua @@ -5,6 +5,7 @@ local a = autoload("conjure.aniseed.core") local str = autoload("conjure.aniseed.string") local client = autoload("conjure.client") local log = autoload("conjure.log") +local text = autoload("conjure.text") local stdio = autoload("conjure.remote.stdio-rt") local config = autoload("conjure.config") local mapping = autoload("conjure.mapping") @@ -65,15 +66,19 @@ local function __3elist(s) return {s} end end +local function prep_code(opts) + local node = a.get(opts, "node") + local suffix + if (node and ("statement" == node:type())) then + suffix = ";\n" + else + suffix = "\n" + end + local code = string.gsub(opts.code, "%s*%-%-[^\n]*$", "") + return (code .. suffix) +end local function eval_str(opts) - local function _9_(repl) - local node = a.get(opts, "node") - local suffix - if (node and ("statement" == node:type())) then - suffix = ";\n" - else - suffix = "\n" - end + local function _10_(repl) local function _11_(msgs) local msgs0 = __3elist(msgs) if opts["on-result"] then @@ -82,9 +87,9 @@ local function eval_str(opts) end return a["run!"](display_result, msgs0) end - return repl.send((opts.code .. suffix), _11_, {["batch?"] = false}) + return repl.send(prep_code(opts), _11_, {["batch?"] = false}) end - return with_repl_or_warn(_9_) + return with_repl_or_warn(_10_) end local function eval_file(opts) return eval_str(a.assoc(opts, "code", a.slurp(opts["file-path"]))) @@ -157,4 +162,4 @@ local function on_filetype() mapping.buf("SqlStop", cfg({"mapping", "stop"}), stop, {desc = "Stop the REPL"}) return mapping.buf("SqlInterrupt", cfg({"mapping", "interrupt"}), interrupt, {desc = "Interrupt the current REPL"}) end -return {["buf-suffix"] = buf_suffix, ["comment-prefix"] = comment_prefix, ["get-form-modifier"] = get_form_modifier, ["comment-node?"] = comment_node_3f, ["->list"] = __3elist, ["eval-str"] = eval_str, ["eval-file"] = eval_file, interrupt = interrupt, stop = stop, start = start, ["on-load"] = on_load, ["on-exit"] = on_exit, ["on-filetype"] = on_filetype} +return {["buf-suffix"] = buf_suffix, ["comment-prefix"] = comment_prefix, ["get-form-modifier"] = get_form_modifier, ["comment-node?"] = comment_node_3f, ["->list"] = __3elist, ["prep-code"] = prep_code, ["eval-str"] = eval_str, ["eval-file"] = eval_file, interrupt = interrupt, stop = stop, start = start, ["on-load"] = on_load, ["on-exit"] = on_exit, ["on-filetype"] = on_filetype}