diff --git a/sqlog/compiler.fnl b/sqlog/compiler.fnl index c116c64..5265302 100644 --- a/sqlog/compiler.fnl +++ b/sqlog/compiler.fnl @@ -161,7 +161,7 @@ (where [op] (. comparitors op)) (add-clause analysis literal) _ (error (.. "Expected literal or comparison but got " (fv literal))))) -(local infix-ops (collect [_ op (ipairs [:+ :- :* :/ :< :> :<= :>= := :|| :and :or])] op true)) +(local infix-ops (collect [_ op (ipairs [:+ :- :* :/ :< :> :<= :>= := :|| :and :or :%])] op true)) (fn Compiler.gen-expr [self analysis expr] "Generates SQL code for a given expression tree." (match expr @@ -172,7 +172,10 @@ _ (.. "c" icolumn))) [:rowid itable] (.. "_t" itable "._rowid_") [:as subexpr name] (.. (self:gen-expr analysis subexpr) " AS " (quoteid name)) - [:set column subexpr] (.. column " = " (self:gen-expr analysis subexpr)) + [:set column subexpr] (.. (quoteid column) " = " (self:gen-expr analysis subexpr)) + [:case & clauses] (.. "CASE " (cat clauses " " #(self:gen-expr analysis $1)) " END") + [:when cmp result] (.. "WHEN " (self:gen-expr analysis cmp) " THEN " (self:gen-expr analysis result)) + [:else result] (.. "ELSE " (self:gen-expr analysis result)) (where [:var name] (. analysis.variable-mapping name)) (self:gen-expr analysis (. analysis.variable-mapping name)) (where [op lhs rhs] (. infix-ops op)) (.. "(" (self:gen-expr analysis lhs) " " op " " (self:gen-expr analysis rhs) ")") [funcname & args] (.. funcname "(" (cat args ", " #(self:gen-expr analysis $1)) ")") diff --git a/sqlog/init.fnl b/sqlog/init.fnl index 5e4e870..1b5c39e 100644 --- a/sqlog/init.fnl +++ b/sqlog/init.fnl @@ -11,34 +11,40 @@ (fn Sqlog.deftable [self name ...] (self:execute (self.compiler:deftable name ...))) (fn Sqlog.defrule [self head ...] (self.compiler:defrule head ...)) +(fn multi? [analysis] (and analysis (> (length analysis) 0))) (fn Sqlog.compile-sql [self analysis] - (when (= analysis.stmt nil) - (let [stmt (sqlite.assert (sqlite.prepare self.db analysis.query))] - (sqlite.bind stmt analysis.constants) - (set analysis.stmt stmt))) + (if (multi? analysis) (each [_ a (ipairs analysis)] (self:compile-sql a)) + (when (= analysis.stmt nil) + (let [stmt (sqlite.assert (sqlite.prepare self.db analysis.query))] + (sqlite.bind stmt analysis.constants) + (set analysis.stmt stmt)))) analysis) (fn Sqlog.execute [self analysis ?collect-results] - (self:compile-sql analysis) - (sqlite.reset analysis.stmt) - (if ?collect-results - (let [result []] - (while (= SQLITE_ROW (sqlite.step analysis.stmt)) - (table.insert result (collect [icol expr (ipairs analysis.selection)] - (match expr - [:as _ name] name - _ icol) - (sqlite.column analysis.stmt icol)))) - result) - (sqlite.step analysis.stmt))) + (if (multi? analysis) (icollect [_ a (ipairs analysis)] (self:execute a ?collect-results)) + (do (print "running:" analysis.query (fv analysis.constants)) + (self:compile-sql analysis) + (sqlite.reset analysis.stmt) + (if ?collect-results + (let [result []] + (while (= SQLITE_ROW (sqlite.step analysis.stmt)) + (table.insert result (collect [icol expr (ipairs analysis.selection)] + (match expr + [:as _ name] name + _ icol) + (sqlite.column analysis.stmt icol)))) + result) + (sqlite.step analysis.stmt))))) (fn Sqlog.compile-action [self action] (self:compile-sql (match action - [:!+ & insert] (self.compiler:insert (table.unpack insert)) - [:literal] (self.compiler:insert action) - [:!- & delete] (self.compiler:delete (table.unpack delete)) - [:!= & update] (self.compiler:update (table.unpack update))))) + [:do & actions] (icollect [_ act (ipairs actions)] (self:compile-action act)) + [:!+ & insert] (self.compiler:insert (table.unpack insert)) + [:literal] (self.compiler:insert action) + [:!- & delete] (self.compiler:delete (table.unpack delete)) + [:!= & update] (self.compiler:update (table.unpack update)) + _ (error (.. "No such action " (fv action)))))) (fn Sqlog.compile-query [self ...] (self:compile-sql (self.compiler:query ...))) diff --git a/sqlog/sqltest.fnl b/sqlog/sqltest.fnl index f1951fe..2ea997b 100644 --- a/sqlog/sqltest.fnl +++ b/sqlog/sqltest.fnl @@ -1,4 +1,5 @@ (local Sqlog (require :sqlog)) +(local {: show} (require :inspector.debug)) (import-macros {: $ : query : specify} :sqlog.macros) (local s (Sqlog)) @@ -13,5 +14,5 @@ [parent :bob #(.. :fred :dy)] [parent :fred :jim] [parent :fred :betty]) -(pp (query s [ancestor :bob descendant gen])) +(show (query s [ancestor (case descendant (when "bob jr" :bob) (else :jim)) descendant gen]))