Implement :?foo [:param :foo] and primitive [:raw "sql"]
This commit is contained in:
parent
ddef4068ba
commit
9f8d1a8564
3 changed files with 47 additions and 26 deletions
|
|
@ -317,8 +317,8 @@ Keywords that begin with `?` are interpreted as bindable parameters:
|
||||||
(-> (select :id)
|
(-> (select :id)
|
||||||
(from :foo)
|
(from :foo)
|
||||||
(where [:= :a :?baz])
|
(where [:= :a :?baz])
|
||||||
(sql/format :params {:baz "BAZ"}))
|
(sql/format {:params {:baz "BAZ"}}))
|
||||||
=> ["SELECT id FROM foo WHERE a = ?" "BAZ"]
|
=> ["SELECT id FROM foo WHERE (a = ?)" "BAZ"]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Miscellaneous
|
### Miscellaneous
|
||||||
|
|
|
||||||
|
|
@ -86,27 +86,39 @@
|
||||||
|
|
||||||
(defn- format-entity [x & [{:keys [aliased? drop-ns?]}]]
|
(defn- format-entity [x & [{:keys [aliased? drop-ns?]}]]
|
||||||
(let [q (if *quoted* (:quote *dialect*) identity)
|
(let [q (if *quoted* (:quote *dialect*) identity)
|
||||||
call (fn [f x] (str f "(" x ")"))
|
[t c] (if-let [n (when-not (or drop-ns? (string? x))
|
||||||
[f t c] (if-let [n (when-not (or drop-ns? (string? x))
|
|
||||||
(namespace x))]
|
(namespace x))]
|
||||||
[nil n (name x)]
|
[n (name x)]
|
||||||
(let [[t c] (if aliased?
|
(if aliased?
|
||||||
[(name x)]
|
[nil (name x)]
|
||||||
(str/split (name x) #"\."))]
|
(let [[t c] (str/split (name x) #"\.")]
|
||||||
;; I really dislike like %func.arg shorthand syntax!
|
(if c [t c] [nil t]))))]
|
||||||
(cond (= \% (first t))
|
|
||||||
[(subs t 1) nil c]
|
|
||||||
c
|
|
||||||
[nil t c]
|
|
||||||
:else
|
|
||||||
[nil nil t])))]
|
|
||||||
(cond->> c
|
(cond->> c
|
||||||
(not= "*" c)
|
(not= "*" c)
|
||||||
(q)
|
(q)
|
||||||
t
|
t
|
||||||
(str (q t) ".")
|
(str (q t) "."))))
|
||||||
f
|
|
||||||
(call f))))
|
(defn- ->param [k]
|
||||||
|
(with-meta (constantly k)
|
||||||
|
{::wrapper
|
||||||
|
(fn [fk {:keys [params]}]
|
||||||
|
(let [k (fk)]
|
||||||
|
(if (contains? params k)
|
||||||
|
(get params k)
|
||||||
|
(throw (ex-info (str "missing parameter value for " k)
|
||||||
|
{:params (keys params)})))))}))
|
||||||
|
|
||||||
|
(defn- format-var [x & [opts]]
|
||||||
|
(let [c (name x)]
|
||||||
|
(cond (= \% (first c))
|
||||||
|
(let [[f & args] (str/split (subs c 1) #"\.")]
|
||||||
|
;; TODO: this does not quote arguments -- does that matter?
|
||||||
|
[(str f "(" (str/join "," args) ")")])
|
||||||
|
(= \? (first c))
|
||||||
|
["?" (->param (keyword (subs c 1)))]
|
||||||
|
:else
|
||||||
|
[(format-entity x opts)])))
|
||||||
|
|
||||||
(defn- format-entity-alias [x]
|
(defn- format-entity-alias [x]
|
||||||
(cond (sequential? x)
|
(cond (sequential? x)
|
||||||
|
|
@ -151,7 +163,9 @@
|
||||||
(into params')))
|
(into params')))
|
||||||
|
|
||||||
(or (keyword? x) (symbol? x))
|
(or (keyword? x) (symbol? x))
|
||||||
|
(if aliased?
|
||||||
[(format-entity x opts)]
|
[(format-entity x opts)]
|
||||||
|
(format-var x opts))
|
||||||
|
|
||||||
(and aliased? (string? x))
|
(and aliased? (string? x))
|
||||||
[(format-entity x opts)]
|
[(format-entity x opts)]
|
||||||
|
|
@ -419,7 +433,7 @@
|
||||||
;:order-by 190
|
;:order-by 190
|
||||||
;:limit 200
|
;:limit 200
|
||||||
;:offset 210
|
;:offset 210
|
||||||
:lock 215
|
;:lock 215
|
||||||
;:values 220
|
;:values 220
|
||||||
:query-values 230})
|
:query-values 230})
|
||||||
;; :on-conflict -- https://www.postgresqltutorial.com/postgresql-upsert/
|
;; :on-conflict -- https://www.postgresqltutorial.com/postgresql-upsert/
|
||||||
|
|
@ -517,11 +531,18 @@
|
||||||
:not
|
:not
|
||||||
(fn [_ [x]]
|
(fn [_ [x]]
|
||||||
(let [[sql & params] (format-expr x)]
|
(let [[sql & params] (format-expr x)]
|
||||||
(into [(str "NOT " sql)] params)))}))
|
(into [(str "NOT " sql)] params)))
|
||||||
|
:param
|
||||||
|
(fn [_ [k]]
|
||||||
|
["?" (->param k)])
|
||||||
|
:raw
|
||||||
|
;; TODO: only supports single raw string right now
|
||||||
|
(fn [_ [s]]
|
||||||
|
[s])}))
|
||||||
|
|
||||||
(defn format-expr [x & [{:keys [nested?] :as opts}]]
|
(defn format-expr [x & [{:keys [nested?] :as opts}]]
|
||||||
(cond (or (keyword? x) (symbol? x))
|
(cond (or (keyword? x) (symbol? x))
|
||||||
[(format-entity x opts)]
|
(format-var x opts)
|
||||||
|
|
||||||
(map? x)
|
(map? x)
|
||||||
(format-dsl x (assoc opts :nested? true))
|
(format-dsl x (assoc opts :nested? true))
|
||||||
|
|
|
||||||
|
|
@ -317,8 +317,8 @@ WHERE kind <> ?
|
||||||
(-> (select :id)
|
(-> (select :id)
|
||||||
(from :foo)
|
(from :foo)
|
||||||
(where [:= :a :?baz])
|
(where [:= :a :?baz])
|
||||||
(sql/format :params {:baz "BAZ"}))
|
(sql/format {:params {:baz "BAZ"}}))
|
||||||
=> ["SELECT id FROM foo WHERE a = ?" "BAZ"]
|
=> ["SELECT id FROM foo WHERE (a = ?)" "BAZ"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue