:insert-into should support abitrary functions for table fixes #402
This commit is contained in:
parent
13a8aa11b2
commit
124fac6f28
2 changed files with 79 additions and 57 deletions
|
|
@ -299,13 +299,21 @@
|
||||||
(when (map? s)
|
(when (map? s)
|
||||||
(throw (ex-info "selectable cannot be statement!"
|
(throw (ex-info "selectable cannot be statement!"
|
||||||
{:selectable s})))
|
{:selectable s})))
|
||||||
(cond-> (format-entity s)
|
(let [[sql & params] (format-expr s)]
|
||||||
|
(into [(cond-> sql
|
||||||
pair?
|
pair?
|
||||||
(str (if (and (contains? *dialect* :as) (not (:as *dialect*))) " " " AS ")
|
(str (if (and (contains? *dialect* :as) (not (:as *dialect*))) " " " AS ")
|
||||||
(format-entity (second x) {:aliased true}))))
|
(format-entity (second x) {:aliased true})))]
|
||||||
|
params)))
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(format-entity x)))
|
[(format-entity x)]))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(format-expr :a)
|
||||||
|
(format-expr [:raw "My String"])
|
||||||
|
(format-entity-alias [[:raw "My String"]])
|
||||||
|
)
|
||||||
|
|
||||||
(declare format-selects-common)
|
(declare format-selects-common)
|
||||||
|
|
||||||
|
|
@ -378,14 +386,16 @@
|
||||||
:else
|
:else
|
||||||
(format-expr x)))
|
(format-expr x)))
|
||||||
|
|
||||||
;; primary clauses
|
(defn- reduce-sql [xs]
|
||||||
|
|
||||||
(defn- format-on-set-op [k xs]
|
|
||||||
(let [[sqls params]
|
|
||||||
(reduce (fn [[sql params] [sql' & params']]
|
(reduce (fn [[sql params] [sql' & params']]
|
||||||
[(conj sql sql') (if params' (into params params') params)])
|
[(conj sql sql') (if params' (into params params') params)])
|
||||||
[[] []]
|
[[] []]
|
||||||
(map #(format-dsl %) xs))]
|
xs))
|
||||||
|
|
||||||
|
;; primary clauses
|
||||||
|
|
||||||
|
(defn- format-on-set-op [k xs]
|
||||||
|
(let [[sqls params] (reduce-sql (map #(format-dsl %) xs))]
|
||||||
(into [(str/join (str " " (sql-kw k) " ") sqls)] params)))
|
(into [(str/join (str " " (sql-kw k) " ") sqls)] params)))
|
||||||
|
|
||||||
(defn format-expr-list
|
(defn format-expr-list
|
||||||
|
|
@ -406,10 +416,7 @@
|
||||||
(throw (ex-info (str "format-expr-list expects a sequence of expressions, found: "
|
(throw (ex-info (str "format-expr-list expects a sequence of expressions, found: "
|
||||||
(type exprs))
|
(type exprs))
|
||||||
{:exprs exprs})))
|
{:exprs exprs})))
|
||||||
(reduce (fn [[sql params] [sql' & params']]
|
(reduce-sql (map #(format-expr % opts) exprs)))
|
||||||
[(conj sql sql') (if params' (into params params') params)])
|
|
||||||
[[] []]
|
|
||||||
(map #(format-expr % opts) exprs)))
|
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(format-expr-list :?tags)
|
(format-expr-list :?tags)
|
||||||
|
|
@ -421,11 +428,7 @@
|
||||||
|
|
||||||
(defn- format-selects-common [prefix as xs]
|
(defn- format-selects-common [prefix as xs]
|
||||||
(if (sequential? xs)
|
(if (sequential? xs)
|
||||||
(let [[sqls params]
|
(let [[sqls params] (reduce-sql (map #(format-selectable-dsl % {:as as}) xs))]
|
||||||
(reduce (fn [[sql params] [sql' & params']]
|
|
||||||
[(conj sql sql') (if params' (into params params') params)])
|
|
||||||
[[] []]
|
|
||||||
(map #(format-selectable-dsl % {:as as}) xs))]
|
|
||||||
(when-not (= :none *checking*)
|
(when-not (= :none *checking*)
|
||||||
(when (empty? xs)
|
(when (empty? xs)
|
||||||
(throw (ex-info (str prefix " empty column list is illegal")
|
(throw (ex-info (str prefix " empty column list is illegal")
|
||||||
|
|
@ -502,10 +505,7 @@
|
||||||
;; TODO: a sequence of pairs -- X AS expr -- where X is either [entity expr]
|
;; TODO: a sequence of pairs -- X AS expr -- where X is either [entity expr]
|
||||||
;; or just entity, as far as I can tell...
|
;; or just entity, as far as I can tell...
|
||||||
(let [[sqls params]
|
(let [[sqls params]
|
||||||
(reduce (fn [[sql params] [sql' & params']]
|
(reduce-sql (map (fn [[x expr]]
|
||||||
[(conj sql sql') (if params' (into params params') params)])
|
|
||||||
[[] []]
|
|
||||||
(map (fn [[x expr]]
|
|
||||||
(let [[sql & params] (format-with-part x)
|
(let [[sql & params] (format-with-part x)
|
||||||
[sql' & params'] (format-dsl expr)]
|
[sql' & params'] (format-dsl expr)]
|
||||||
;; according to docs, CTE should _always_ be wrapped:
|
;; according to docs, CTE should _always_ be wrapped:
|
||||||
|
|
@ -526,24 +526,38 @@
|
||||||
(if (and (sequential? table) (sequential? (second table)))
|
(if (and (sequential? table) (sequential? (second table)))
|
||||||
table
|
table
|
||||||
[table])
|
[table])
|
||||||
[sql & params] (format-dsl statement)]
|
[sql & params] (format-dsl statement)
|
||||||
(into [(str (sql-kw k) " " (format-entity-alias table)
|
[t-sql & t-params] (format-entity-alias table)
|
||||||
|
[c-sqls c-params] (reduce-sql (map #'format-entity-alias cols))]
|
||||||
|
(-> [(str (sql-kw k) " " t-sql
|
||||||
" "
|
" "
|
||||||
(when (seq cols)
|
(when (seq cols)
|
||||||
(str "("
|
(str "("
|
||||||
(str/join ", " (map #'format-entity-alias cols))
|
(str/join ", " c-sqls)
|
||||||
") "))
|
") "))
|
||||||
sql)]
|
sql)]
|
||||||
params))
|
(into t-params)
|
||||||
|
(into c-params)
|
||||||
|
(into params)))
|
||||||
(sequential? (second table))
|
(sequential? (second table))
|
||||||
(let [[table cols] table]
|
(let [[table cols] table
|
||||||
[(str (sql-kw k) " " (format-entity-alias table)
|
[t-sql & t-params] (format-entity-alias table)
|
||||||
|
[c-sqls c-params] (reduce-sql (map #'format-entity-alias cols))]
|
||||||
|
(-> [(str (sql-kw k) " " t-sql
|
||||||
" ("
|
" ("
|
||||||
(str/join ", " (map #'format-entity-alias cols))
|
(str/join ", " c-sqls)
|
||||||
")")])
|
")")]
|
||||||
|
(into t-params)
|
||||||
|
(into c-params)))
|
||||||
:else
|
:else
|
||||||
[(str (sql-kw k) " " (format-entity-alias table))])
|
(let [[sql & params] (format-entity-alias table)]
|
||||||
[(str (sql-kw k) " " (format-entity-alias table))]))
|
(into [(str (sql-kw k) " " sql)] params)))
|
||||||
|
(let [[sql & params] (format-entity-alias table)]
|
||||||
|
(into [(str (sql-kw k) " " sql)] params))))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(format-insert :insert-into [[[:raw ":foo"]] {:select :bar}])
|
||||||
|
)
|
||||||
|
|
||||||
(defn- format-join [k clauses]
|
(defn- format-join [k clauses]
|
||||||
(let [[sqls params]
|
(let [[sqls params]
|
||||||
|
|
@ -555,12 +569,14 @@
|
||||||
[j])
|
[j])
|
||||||
sqls (conj sqls sql-j)]
|
sqls (conj sqls sql-j)]
|
||||||
(if (and (sequential? e) (= :using (first e)))
|
(if (and (sequential? e) (= :using (first e)))
|
||||||
|
(let [[u-sqls u-params]
|
||||||
|
(reduce-sql (map #'format-entity-alias (rest e)))]
|
||||||
[(conj sqls
|
[(conj sqls
|
||||||
"USING"
|
"USING"
|
||||||
(str "("
|
(str "("
|
||||||
(str/join ", " (map #'format-entity-alias (rest e)))
|
(str/join ", " u-sqls)
|
||||||
")"))
|
")"))
|
||||||
(into params params-j)]
|
(-> params (into params-j) (into u-params))])
|
||||||
(let [[sql & params'] (when e (format-expr e))]
|
(let [[sql & params'] (when e (format-expr e))]
|
||||||
[(cond-> sqls e (conj "ON" sql))
|
[(cond-> sqls e (conj "ON" sql))
|
||||||
(-> params
|
(-> params
|
||||||
|
|
@ -1326,11 +1342,7 @@
|
||||||
(remove nil? expr)
|
(remove nil? expr)
|
||||||
expr)
|
expr)
|
||||||
[sqls params]
|
[sqls params]
|
||||||
(reduce (fn [[sql params] [sql' & params']]
|
(reduce-sql (map #(format-expr % {:nested true})
|
||||||
[(conj sql sql')
|
|
||||||
(if params' (into params params') params)])
|
|
||||||
[[] []]
|
|
||||||
(map #(format-expr % {:nested true})
|
|
||||||
(rest x)))]
|
(rest x)))]
|
||||||
(into [(cond-> (str/join (str " " (sql-kw op) " ") sqls)
|
(into [(cond-> (str/join (str " " (sql-kw op) " ") sqls)
|
||||||
nested
|
nested
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,16 @@
|
||||||
(is (or (= res ["INSERT INTO foo (id, bar) VALUES (?, ?), (?, NULL)" 1 "quux" 2])
|
(is (or (= res ["INSERT INTO foo (id, bar) VALUES (?, ?), (?, NULL)" 1 "quux" 2])
|
||||||
(= res ["INSERT INTO foo (bar, id) VALUES (?, ?), (NULL, ?)" "quux" 1 2])))))
|
(= res ["INSERT INTO foo (bar, id) VALUES (?, ?), (NULL, ?)" "quux" 1 2])))))
|
||||||
|
|
||||||
|
(deftest insert-into-functions
|
||||||
|
;; needs [[:raw ..]] because it's the columns case:
|
||||||
|
(is (= (format {:insert-into [[[:raw "My-Table Name"]] {:select [:bar] :from [:baz]}]})
|
||||||
|
["INSERT INTO My-Table Name SELECT bar FROM baz"]))
|
||||||
|
;; this variant only needs [:raw ..]
|
||||||
|
(is (= (format {:insert-into [[:raw "My-Table Name"]] :values [{:foo/id 1}]})
|
||||||
|
["INSERT INTO My-Table Name (id) VALUES (?)" 1]))
|
||||||
|
(is (= (format {:insert-into [:foo :bar] :values [{:foo/id 1}]})
|
||||||
|
["INSERT INTO foo AS bar (id) VALUES (?)" 1])))
|
||||||
|
|
||||||
(deftest exists-test
|
(deftest exists-test
|
||||||
;; EXISTS should never have been implemented as SQL syntax: it's an operator!
|
;; EXISTS should never have been implemented as SQL syntax: it's an operator!
|
||||||
#_(is (= (format {:exists {:select [:a] :from [:foo]}})
|
#_(is (= (format {:exists {:select [:a] :from [:foo]}})
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue