summaryrefslogtreecommitdiff
path: root/src/clojure_sql/compiler.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/clojure_sql/compiler.clj')
-rw-r--r--src/clojure_sql/compiler.clj74
1 files changed, 53 insertions, 21 deletions
diff --git a/src/clojure_sql/compiler.clj b/src/clojure_sql/compiler.clj
index 6f940c0..60a5530 100644
--- a/src/clojure_sql/compiler.clj
+++ b/src/clojure_sql/compiler.clj
@@ -50,18 +50,27 @@
;; ==============================================================
;; compile-* multimethods are of the signature:
-;; (db, expr) -> (fn [s] [sql])
+;; (db, expr) -> [args] -> [sql & args]
(declare compile-query compile-expression)
-(defmulti compile-expression-sequential (fn [db ex]))
+(defmulti compile-expression-list (fn [db _] db))
+(defmethod compile-expression-list :default [db ex]
+ (->> (map (partial compile-expression db) ex)
+ (apply sequence)
+ ((p-lift string/join ","))
+ $add-parentheses))
+
+(defmulti compile-expression-sequential (fn [db _] db))
(defmethod compile-expression-sequential :default [db ex]
(let [compile-exprs #(map (partial compile-expression db) %)
op (name (first ex))
num-args (dec (count ex))]
(-> (condp u/funcall (first ex)
quote? (do (assert (= num-args 1) "`quote` must only take one argument")
- (>> (tell (second ex)) (return "?")))
+ (if (sequential? (second ex))
+ (compile-expression-list db (second ex))
+ (>> (tell (second ex)) (return "?"))))
unary? (do (assert (= num-args 1) (str "Unary operator `" op "` must take one argument"))
(do-m :let [exprs (compile-exprs ex)]
vals <- (apply sequence exprs)
@@ -120,28 +129,33 @@
(def ^:private join-type-names
{:inner "INNER"
- :left "LEFT OUTER"
- :right "RIGHT OUTER"
- :outer "FULL OUTER"
+ :outer "LEFT OUTER"
+ :full-outer "FULL OUTER"
:cross "CROSS"})
(defmulti compile-tables (fn [db _ _] db))
-(defmethod compile-tables :default [db join tables-map]
- (if (vector? join)
+(defmethod compile-tables :default [db join tables-map]
+ (if (vector? join)
(->> (for [table-alias join]
(make-table-name db (get tables-map table-alias) table-alias))
(apply sequence)
((p-lift string/join ", ")))
(let [{:keys [left right type on]} join]
- ($str (return "(")
- (compile-tables db left tables-map)
- (return (str " " (get join-type-names type (name type)) " JOIN "))
- (compile-tables db right tables-map)
- (if on
- ($str (return " ON ")
- (compile-expression db on))
- (return ""))
- (return ")")))))
+ (if (= type :cross)
+ ($str (return "(")
+ (compile-tables db left tables-map)
+ (return " CROSS JOIN ")
+ (compile-tables db right tables-map)
+ (return ")"))
+ ($str (return "(")
+ (compile-tables db left tables-map)
+ (return (str " " (get join-type-names type (name type)) " JOIN "))
+ (compile-tables db right tables-map)
+ (return " ON ")
+ (if on
+ (compile-expression db on)
+ (return "TRUE"))
+ (return ")"))))))
(defmulti compile-where (fn [db _] db))
(defmethod compile-where :default [db expr]
@@ -149,8 +163,8 @@
($str (return " WHERE ") (compile-expression db expr))
(return nil)))
-(defmulti compile-sort-by (fn [db _] db))
-(defmethod compile-sort-by :default [db fields]
+(defmulti compile-sort (fn [db _] db))
+(defmethod compile-sort :default [db fields]
(if fields
(->> (for [[[table field] dir] fields]
($str (make-field-name db [table field])
@@ -160,8 +174,24 @@
($str (return " ORDER BY ")))
(return nil)))
+(defmulti compile-group (fn [db _] db))
+(defmethod compile-group :default [db fields]
+ (if fields
+ (->> (for [[table field] fields]
+ (make-field-name db [table field]))
+ (apply sequence)
+ ((p-lift string/join ","))
+ ($str (return " GROUP BY ")))
+ (return nil)))
+
+(defmulti compile-having (fn [db _] db))
+(defmethod compile-having :default [db expr]
+ (if expr
+ ($str (return " HAVING ") (compile-expression db expr))
+ (return nil)))
+
(defmulti compile-query (fn [db _] db))
-(defmethod compile-query :default [db {:keys [tables fields joins where sort-by]}]
+(defmethod compile-query :default [db {:keys [tables fields joins where sort group having]}]
($str (return "SELECT ")
(compile-fields db fields)
(if tables
@@ -169,7 +199,9 @@
(compile-tables db joins tables))
($str ""))
(compile-where db where)
- (compile-sort-by db sort-by)))
+ (compile-group db group)
+ (compile-having db having)
+ (compile-sort db sort)))