diff options
Diffstat (limited to 'src/clojure_sql/compiler.clj')
-rw-r--r-- | src/clojure_sql/compiler.clj | 75 |
1 files changed, 39 insertions, 36 deletions
diff --git a/src/clojure_sql/compiler.clj b/src/clojure_sql/compiler.clj index 5bec649..0cbb808 100644 --- a/src/clojure_sql/compiler.clj +++ b/src/clojure_sql/compiler.clj @@ -21,16 +21,16 @@ ;; DB specific escaping methods ;; ============================================================== -(defmulti field-name (fn [db _] db)) -(defmethod field-name :default [_ field] +(defmulti field-name (fn [db _] db) :default :postgres) +(defmethod field-name :postgres [_ field] (str \" (name field) \")) -(defmulti table-name (fn [db _] db)) -(defmethod table-name :default [_ table] +(defmulti table-name (fn [db _] db) :default :postgres) +(defmethod table-name :postgres [_ table] (str \" (name table) \")) -(defmulti function-name (fn [db _] db)) -(defmethod function-name :default [_ function] +(defmulti function-name (fn [db _] db) :default :postgres) +(defmethod function-name :postgres [_ function] (str \" (name function) \")) @@ -70,15 +70,15 @@ (declare compile-query compile-expression) -(defmulti compile-expression-list (fn [db _] db)) -(defmethod compile-expression-list :default [db ex] +(defmulti compile-expression-list (fn [db _] db) :default :postgres) +(defmethod compile-expression-list :postgres [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] +(defmulti compile-expression-sequential (fn [db _] db) :default :postgres) +(defmethod compile-expression-sequential :postgres [db ex] (let [compile-exprs #(map (partial compile-expression db) %) op-name (operator-name (first ex)) num-args (dec (count ex))] @@ -113,8 +113,8 @@ (add-parentheses (string/join "," vals)))))) $add-parentheses))) -(defmulti compile-expression (fn [db _] db)) -(defmethod compile-expression :default [db ex] +(defmulti compile-expression (fn [db _] db) :default :postgres) +(defmethod compile-expression :postgres [db ex] (condp u/funcall ex boolean? (return (string/upper-case (str ex))) query? ($add-parentheses (compile-query db ex)) @@ -144,8 +144,8 @@ (return " AS ") (return (field-name db alias))))) -(defmulti compile-fields (fn [db _] db)) -(defmethod compile-fields :default [db fields-map] +(defmulti compile-fields (fn [db _] db) :default :postgres) +(defmethod compile-fields :postgres [db fields-map] (if (seq fields-map) (->> (for [[alias field] fields-map] (make-field-name db field alias)) @@ -159,8 +159,8 @@ :full-outer "FULL OUTER" :cross "CROSS"}) -(defmulti compile-tables (fn [db _ _] db)) -(defmethod compile-tables :default [db join tables-map] +(defmulti compile-tables (fn [db _ _] db) :default :postgres) +(defmethod compile-tables :postgres [db join tables-map] (if (vector? join) (->> (for [table-alias join] (make-table-name db (get tables-map table-alias) table-alias)) @@ -183,14 +183,14 @@ (return "TRUE")) (return ")")))))) -(defmulti compile-where (fn [db _] db)) -(defmethod compile-where :default [db expr] +(defmulti compile-where (fn [db _] db) :default :postgres) +(defmethod compile-where :postgres [db expr] (if expr ($str (return " WHERE ") (compile-expression db expr)) (return nil))) -(defmulti compile-sort (fn [db _] db)) -(defmethod compile-sort :default [db fields] +(defmulti compile-sort (fn [db _] db) :default :postgres) +(defmethod compile-sort :postgres [db fields] (if fields (->> (for [[[table field] dir] fields] ($str (make-field-name db [table field]) @@ -200,8 +200,8 @@ ($str (return " ORDER BY "))) (return nil))) -(defmulti compile-group (fn [db _] db)) -(defmethod compile-group :default [db fields] +(defmulti compile-group (fn [db _] db) :default :postgres) +(defmethod compile-group :postgres [db fields] (if fields (->> (for [[table field] fields] (make-field-name db [table field])) @@ -210,14 +210,21 @@ ($str (return " GROUP BY "))) (return nil))) -(defmulti compile-having (fn [db _] db)) -(defmethod compile-having :default [db expr] +(defmulti compile-having (fn [db _] db) :default :postgres) +(defmethod compile-having :postgres [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 group having union]}] +(defmulti compile-limit (fn [db _ _] db) :default :postgres) +(defmethod compile-limit :postgres [db take drop] + (return (str (if take + (str " LIMIT " take)) + (if drop + (str " OFFSET " drop))))) + +(defmulti compile-query (fn [db _] db) :default :postgres) +(defmethod compile-query :postgres [db {:keys [tables fields joins where sort group having union take drop]}] (if union (->> union (map (partial compile-query db)) @@ -232,23 +239,19 @@ (compile-where db where) (compile-group db group) (compile-having db having) - (compile-sort db sort)))) + (compile-sort db sort) + (compile-limit db take drop)))) -(defn compile [db query] +(defn compile-select [db query] (let [[sql vars] ((compile-query db query) [])] (vec (cons sql vars)))) -;; Utility functions - -(defn ^:private build-insertion [db fields record] - ) - -(defn insert! [db {:keys [fields tables joins]} & records] +(defn compile-insert [db {:keys [fields tables joins]} & records] (assert (= (count tables) 1) "Cannot insert into a multiple-table query") (let [fields-order (map key fields) wrap #(str "INSERT INTO " @@ -275,7 +278,7 @@ ;; {:uid 10, :name :carlo, :other :stuff} ;; {:uid 1, :name :carl, :other :stuf}) -(defn update! [db {:keys [tables fields where joins]} partial-record] +(defn compile-update [db {:keys [tables fields where joins]} partial-record] (assert (= (count tables) 1) "Cannot delete from a multiple-table query") (assert (seq (set/intersection (set (keys partial-record)) (set (keys fields)))) "At least one field must be being updated") @@ -307,7 +310,7 @@ ;; {:username "carlozancnaro" ;; :blah "blah"}) -(defn delete! [db {:keys [tables where joins]}] +(defn compile-delete [db {:keys [tables where joins]}] (assert (= (count tables) 1) "Cannot delete from a multiple-table query") (let [table (compile-tables db joins tables) where-expression (if where |