This commit is contained in:
Oleksandr Yakushev 2025-05-08 14:19:41 +03:00 committed by GitHub
commit 7001917c0b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -134,30 +134,32 @@
(def ^:private default-numbered (atom false)) (def ^:private default-numbered (atom false))
(def ^:private ^:dynamic *dialect* nil) (def ^:private ^:dynamic *dialect* nil)
;; nil would be a better default but that makes testing individual (def ^:private ^:dynamic *options*
;; functions harder than necessary: {;; nil would be a better default but that makes testing individual
(def ^:private ^:dynamic *clause-order* default-clause-order) ;; functions harder than necessary:
(def ^:private ^:dynamic *quoted* @default-quoted) :clause-order default-clause-order
(def ^:private ^:dynamic *quoted-always* @default-quoted-always) :quoted @default-quoted
(def ^:private ^:dynamic *quoted-snake* @default-quoted-snake) :quoted-always @default-quoted-always
(def ^:private ^:dynamic *inline* @default-inline) :quoted-snake @default-quoted-snake
(def ^:private ^:dynamic *params* nil) :inline @default-inline
(def ^:private ^:dynamic *values-default-columns* nil) :params nil
;; there is no way, currently, to enable suspicious characters :values-default-columns nil
;; in entities; if someone complains about this check, an option ;; there is no way, currently, to enable suspicious characters
;; can be added to format to turn this on: ;; in entities; if someone complains about this check, an option
(def ^:private ^:dynamic *allow-suspicious-entities* false) ;; can be added to format to turn this on:
;; the following metadata is ignored in formatted by default: :allow-suspicious-entities false
;; :file, :line, :column, :end-line, and :end-column ;; the following metadata is ignored in formatted by default:
;; this dynamic var can be used to add more metadata to ignore: ;; :file, :line, :column, :end-line, and :end-column
(def ^:private ^:dynamic *ignored-metadata* []) ;; this dynamic var can be used to add more metadata to ignore:
;; "linting" mode (:none, :basic, :strict): :ignored-metadata []
(def ^:private ^:dynamic *checking* @default-checking) ;; "linting" mode (:none, :basic, :strict):
;; the current DSL hash map being formatted (for clause-body / contains-clause?): :checking @default-checking
(def ^:private ^:dynamic *dsl* nil) ;; the current DSL hash map being formatted (for clause-body / contains-clause?):
;; caching data to detect expressions that cannot be cached: :dsl nil
(def ^:private ^:dynamic *caching* nil) ;; caching data to detect expressions that cannot be cached:
(def ^:private ^:dynamic *numbered* nil) :caching nil
:numbered nil})
;; #533 mostly undocumented dynvar to prevent ? -> ?? escaping: ;; #533 mostly undocumented dynvar to prevent ? -> ?? escaping:
(def ^:no-doc ^:dynamic *escape-?* true) (def ^:no-doc ^:dynamic *escape-?* true)
@ -165,7 +167,7 @@
(def ^:private suspicious ";") (def ^:private suspicious ";")
(defn- suspicious? [s] (str/includes? s suspicious)) (defn- suspicious? [s] (str/includes? s suspicious))
(defn- suspicious-entity-check [entity] (defn- suspicious-entity-check [entity]
(when-not *allow-suspicious-entities* (when-not (:allow-suspicious-entities *options*)
(when (suspicious? entity) (when (suspicious? entity)
(throw (ex-info (str "suspicious character found in entity: " entity) (throw (ex-info (str "suspicious character found in entity: " entity)
{:disallowed suspicious}))))) {:disallowed suspicious})))))
@ -176,11 +178,12 @@
"If the current DSL expression being formatted contains the specified clause "If the current DSL expression being formatted contains the specified clause
(as a keyword or symbol), returns that clause's value." (as a keyword or symbol), returns that clause's value."
[clause] [clause]
(or (get *dsl* clause) (let [dsl (:dsl *options*)]
(get *dsl* (or (get dsl clause)
(if (keyword? clause) (get dsl
(symbol (name clause)) (if (keyword? clause)
(keyword (name clause)))))) (symbol (name clause))
(keyword (name clause)))))))
(defn contains-clause? (defn contains-clause?
"Returns true if the current DSL expression being formatted "Returns true if the current DSL expression being formatted
@ -283,37 +286,38 @@
Handles quoting, splitting at / or ., replacing - with _ etc." Handles quoting, splitting at / or ., replacing - with _ etc."
([e] (format-entity e {})) ([e] (format-entity e {}))
([e {:keys [aliased drop-ns]}] ([e {:keys [aliased drop-ns]}]
(let [e (if (and aliased (keyword? e) (str/starts-with? (name e) "'")) (let [dialect *dialect*
;; #497 quoted alias support (should behave like string) {:keys [quoted quoted-snake quoted-always]} *options*
e (if (and aliased (keyword? e) (str/starts-with? (name e) "'"))
;; #497 quoted alias support (should behave like string)
(subs (name e) 1) (subs (name e) 1)
e) e)
col-fn (or (:col-fn *dialect*) col-fn (or (:col-fn dialect)
(if (or *quoted* (string? e)) (if (or quoted (string? e))
(if *quoted-snake* name-_ name) (if quoted-snake name-_ name)
name-_)) name-_))
col-e (col-fn e) col-e (col-fn e)
dialect-q (:quote *dialect* identity) dialect-q (:quote dialect identity)
quote-fn (cond (or *quoted* (string? e)) quote-fn (cond (or quoted (string? e))
dialect-q dialect-q
;; #422: if default quoting and "unusual" ;; #422: if default quoting and "unusual"
;; characters in entity, then quote it: ;; characters in entity, then quote it:
(nil? *quoted*) (nil? quoted)
(fn opt-quote [part] (fn opt-quote [part]
(cond (and *quoted-always* (cond (some-> quoted-always (re-find part))
(re-find *quoted-always* part))
(dialect-q part) (dialect-q part)
(re-find alphanumeric part) (re-find alphanumeric part)
part part
:else :else
(dialect-q part))) (dialect-q part)))
*quoted-always* quoted-always
(fn always-quote [part] (fn always-quote [part]
(if (re-find *quoted-always* part) (if (re-find quoted-always part)
(dialect-q part) (dialect-q part)
part)) part))
:else :else
identity) identity)
parts-fn (or (:parts-fn *dialect*) parts-fn (or (:parts-fn dialect)
#(if-let [n (when-not (or drop-ns (string? e)) #(if-let [n (when-not (or drop-ns (string? e))
(namespace-_ e))] (namespace-_ e))]
[n %] [n %]
@ -329,10 +333,10 @@
(for [v [:foo-bar "foo-bar" ; symbol is the same as keyword (for [v [:foo-bar "foo-bar" ; symbol is the same as keyword
:f-o.b-r :f-o/b-r] :f-o.b-r :f-o/b-r]
a [true false] d [true false] q [true false]] a [true false] d [true false] q [true false]]
(binding [*dialect* (:mysql @dialects) *quoted* q] (binding [*dialect* (:mysql @dialects) *options* (assoc *options* :quoted q)]
(if q (if q
[v a d (format-entity v {:aliased a :drop-ns d}) [v a d (format-entity v {:aliased a :drop-ns d})
(binding [*quoted-snake* true] (binding [*options* (assoc *options* :quoted-snake true)]
(format-entity v {:aliased a :drop-ns d}))] (format-entity v {:aliased a :drop-ns d}))]
[v a d (format-entity v {:aliased a :drop-ns d})]))) [v a d (format-entity v {:aliased a :drop-ns d})])))
) )
@ -356,7 +360,8 @@
(if (str/starts-with? n "'") (if (str/starts-with? n "'")
(let [ident (subs n 1) (let [ident (subs n 1)
ident-l (str/lower-case ident)] ident-l (str/lower-case ident)]
(binding [*quoted* (when-not (contains? #{"array"} ident-l) *quoted*)] (binding [*options* (cond-> *options*
(= ident-l "array") (assoc :quoted nil))]
(format-entity (keyword ident)))) (format-entity (keyword ident))))
(-> n (dehyphen) (upper-case)))))) (-> n (dehyphen) (upper-case))))))
@ -419,10 +424,11 @@
(defn- sqlize-value [x] (p/sqlize x)) (defn- sqlize-value [x] (p/sqlize x))
(defn- param-value [k] (defn- param-value [k]
(if (contains? *params* k) (let [{:keys [params]} *options*]
(get *params* k) (if (contains? params k)
(throw (ex-info (str "missing parameter value for " k) (get params k)
{:params (keys *params*)})))) (throw (ex-info (str "missing parameter value for " k)
{:params (keys params)})))))
(defn- ->param [k] (defn- ->param [k]
(with-meta (constantly k) (with-meta (constantly k)
@ -430,18 +436,18 @@
(fn [fk _] (param-value (fk)))})) (fn [fk _] (param-value (fk)))}))
(defn ->numbered [v] (defn ->numbered [v]
(let [n (count (swap! *numbered* conj v))] (let [{:keys [numbered]} *options*
n (count (swap! numbered conj v))]
[(str "$" n) (with-meta (constantly (dec n)) [(str "$" n) (with-meta (constantly (dec n))
{::wrapper {::wrapper
(fn [fk _] (get @*numbered* (fk)))})])) (fn [fk _] (get @numbered (fk)))})]))
(defn ->numbered-param [k] (defn ->numbered-param [k]
(let [n (count (swap! *numbered* conj k))] (let [{:keys [numbered]} *options*
n (count (swap! numbered conj k))]
[(str "$" n) (with-meta (constantly (dec n)) [(str "$" n) (with-meta (constantly (dec n))
{::wrapper {::wrapper
(fn [fk _] (param-value (get @*numbered* (fk))))})])) (fn [fk _] (param-value (get @numbered (fk))))})]))
(def ^:private ^:dynamic *formatted-column* (atom false))
(defn- format-fn-name (defn- format-fn-name
[x] [x]
@ -457,9 +463,7 @@
(format-simple-var x c {}))) (format-simple-var x c {})))
([x c opts] ([x c opts]
(if (str/starts-with? c "'") (if (str/starts-with? c "'")
(do (subs c 1)
(reset! *formatted-column* true)
(subs c 1))
(format-entity x opts)))) (format-entity x opts))))
(defn- format-var (defn- format-var
@ -468,7 +472,8 @@
;; rather than name/namespace, we want to allow ;; rather than name/namespace, we want to allow
;; for multiple / in the %fun.call case so that ;; for multiple / in the %fun.call case so that
;; qualified column names can be used: ;; qualified column names can be used:
(let [c (if (keyword? x) (let [{:keys [inline numbered]} *options*
c (if (keyword? x)
#?(:bb (subs (str x) 1) #?(:bb (subs (str x) 1)
:clj (str (.sym ^clojure.lang.Keyword x)) :clj (str (.sym ^clojure.lang.Keyword x))
:default (subs (str x) 1)) :default (subs (str x) 1))
@ -480,9 +485,9 @@
")")]) ")")])
(str/starts-with? c "?") (str/starts-with? c "?")
(let [k (keyword (subs c 1))] (let [k (keyword (subs c 1))]
(cond *inline* (cond inline
[(sqlize-value (param-value k))] [(sqlize-value (param-value k))]
*numbered* numbered
(->numbered-param k) (->numbered-param k)
:else :else
["?" (->param k)])) ["?" (->param k)]))
@ -633,14 +638,14 @@
(into [; remove the somewhat "standard" metadata: (into [; remove the somewhat "standard" metadata:
:line :column :file :line :column :file
:end-line :end-column] :end-line :end-column]
*ignored-metadata*)))] (:ignored-metadata *options*))))]
(when (seq items) (when (seq items)
(join (str sep " ") (map sql-kw) items)))))) (join (str sep " ") (map sql-kw) items))))))
(comment (comment
(format-meta ^{:foo true :bar :baz :original {:line 1} :top 10} []) (format-meta ^{:foo true :bar :baz :original {:line 1} :top 10} [])
(binding [*ignored-metadata* [:bar]] (binding [*options* {:ignored-metadata [:bar]}]
(format-meta ^{:foo true :bar :baz} [])) (format-meta ^{:foo true :bar :baz} []))
(format-meta []) (format-meta [])
@ -682,7 +687,7 @@
(str (if as (str (if as
(if (or *-qualifier (if (or *-qualifier
(and (contains? *dialect* :as) (and (contains? *dialect* :as)
(not (:as *dialect*)))) (not (:as *dialect*))))
" " " "
" AS ") " AS ")
" ") " ")
@ -819,7 +824,7 @@
["(" ")"])] ["(" ")"])]
(if (sequential? xs) (if (sequential? xs)
(let [[sqls params] (reduce-sql (map #(format-selectable-dsl % {:as as})) xs)] (let [[sqls params] (reduce-sql (map #(format-selectable-dsl % {:as as})) xs)]
(when-not (= :none *checking*) (when-not (= :none (:checking *options*))
(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")
{:clause (into [prefix] xs)})))) {:clause (into [prefix] xs)}))))
@ -1165,26 +1170,28 @@
;; use the keys from the first map if they match so that ;; use the keys from the first map if they match so that
;; users can rely on the key ordering if they want to, ;; users can rely on the key ordering if they want to,
;; e.g., see test that uses array-map for the first row ;; e.g., see test that uses array-map for the first row
cols-n (into #{} (mapcat keys) (filter map? xs)) cols-n (into #{} (comp (filter map?) (mapcat keys)) xs)
cols (if (= (set cols-1) cols-n) cols-1 cols-n)] cols (if (= (into #{} cols-1) cols-n) cols-1 cols-n)]
[cols (when-not skip-cols-sql [cols (when-not skip-cols-sql
(str "(" (str "("
(join ", " (map #(format-entity % {:drop-ns true})) cols) (join ", " (map #(format-entity % {:drop-ns true})) cols)
")"))])))) ")"))]))))
(defn- format-values [k xs] (defn- format-values [k xs]
(let [first-xs (when (sequential? xs) (first (drop-while ident? xs))) (let [{:keys [values-default-columns]} *options*
first-xs (when (sequential? xs) (first (drop-while ident? xs)))
row-ctr (and (sequential? xs) row-ctr (and (sequential? xs)
(ident? (first xs)) (ident? (first xs))
(contains? #{:row 'row} (first xs))) (contains? #{:row 'row} (first xs)))
xs (if row-ctr (rest xs) xs)] xs (if (sequential? xs) (vec xs) xs)
xs (if row-ctr (subvec xs 1) xs)]
(cond (and (ident? xs) (contains? #{:default 'default} xs)) (cond (and (ident? xs) (contains? #{:default 'default} xs))
[(str (sql-kw xs) " " (sql-kw k))] [(str (sql-kw xs) " " (sql-kw k))]
(empty? xs) (empty? xs)
[(str (sql-kw k) " ()")] [(str (sql-kw k) " ()")]
(sequential? first-xs) (sequential? first-xs)
;; [[1 2 3] [4 5 6]] ;; [[1 2 3] [4 5 6]]
(let [n-1 (map count (filter sequential? xs)) (let [n-1 (into [] (comp (filter sequential?) (map count)) xs)
;; issue #291: ensure all value sequences are the same length ;; issue #291: ensure all value sequences are the same length
xs' (if (apply = n-1) xs' (if (apply = n-1)
xs xs
@ -1225,9 +1232,8 @@
(get x % (get x %
;; issue #366: use NULL or DEFAULT ;; issue #366: use NULL or DEFAULT
;; for missing column values: ;; for missing column values:
(if (contains? *values-default-columns* %) (when (contains? values-default-columns %)
[:default] [:default]))))
nil))))
cols)] cols)]
[(conj sql [(conj sql
(if (sequential? sqls') (if (sequential? sqls')
@ -1312,7 +1318,7 @@
[(str (sql-kw k) " " e " = EXCLUDED." e)]))) [(str (sql-kw k) " " e " = EXCLUDED." e)])))
(defn- format-simple-clause [c context] (defn- format-simple-clause [c context]
(binding [*inline* true] (binding [*options* (assoc *options* :inline true)]
(let [[sql & params] (format-dsl c)] (let [[sql & params] (format-dsl c)]
(when (seq params) (when (seq params)
(throw (ex-info (str "parameters are not accepted in " context) (throw (ex-info (str "parameters are not accepted in " context)
@ -1320,7 +1326,7 @@
sql))) sql)))
(defn- format-simple-expr [e context] (defn- format-simple-expr [e context]
(binding [*inline* true] (binding [*options* (assoc *options* :inline true)]
(let [[sql & params] (format-expr e)] (let [[sql & params] (format-expr e)]
(when (seq params) (when (seq params)
(throw (ex-info (str "parameters are not accepted in " context) (throw (ex-info (str "parameters are not accepted in " context)
@ -1570,7 +1576,7 @@
(into [(str (sql-kw k) " " sql " " (into [(str (sql-kw k) " " sql " "
(join " " (map sql-kw) units))] (join " " (map sql-kw) units))]
params)) params))
(binding [*inline* true] (binding [*options* (assoc *options* :inline true)]
(let [[sql & params] (format-expr n)] (let [[sql & params] (format-expr n)]
(into [(str (sql-kw k) " " sql)] params))))) (into [(str (sql-kw k) " " sql)] params)))))
[(str (sql-kw k) " " (sql-kw args))])) [(str (sql-kw k) " " (sql-kw args))]))
@ -1613,10 +1619,11 @@
a non-empty where clause if at least basic checking is enabled." a non-empty where clause if at least basic checking is enabled."
[formatter] [formatter]
(fn [k xs] (fn [k xs]
(when-not (= :none *checking*) (let [{:keys [checking dsl]} *options*]
(when-not (seq (:where *dsl*)) (when-not (= :none checking)
(throw (ex-info (str (sql-kw k) " without a non-empty WHERE clause is dangerous") (when (empty? (:where dsl))
{:clause k :where (:where *dsl*)})))) (throw (ex-info (str (sql-kw k) " without a non-empty WHERE clause is dangerous")
{:clause k :where (:where dsl)})))))
(formatter k xs))) (formatter k xs)))
(def ^:private base-clause-order (def ^:private base-clause-order
@ -1759,7 +1766,7 @@
extend the DSL supported by HoneySQL." extend the DSL supported by HoneySQL."
([statement-map] (format-dsl statement-map {})) ([statement-map] (format-dsl statement-map {}))
([statement-map {:keys [aliased nested pretty]}] ([statement-map {:keys [aliased nested pretty]}]
(binding [*dsl* statement-map] (binding [*options* (assoc *options* :dsl statement-map)]
(let [[sqls params leftover] (let [[sqls params leftover]
(reduce (fn [[sql params leftover] k] (reduce (fn [[sql params leftover] k]
(if-some [xs (if-some [xs (k leftover)] (if-some [xs (if-some [xs (k leftover)]
@ -1773,7 +1780,7 @@
(dissoc leftover k (kw->sym k))]) (dissoc leftover k (kw->sym k))])
[sql params leftover])) [sql params leftover]))
[[] [] statement-map] [[] [] statement-map]
*clause-order*)] (:clause-order *options*))]
(if (seq leftover) (if (seq leftover)
(throw (ex-info (str "These SQL clauses are unknown or have nil values: " (throw (ex-info (str "These SQL clauses are unknown or have nil values: "
(join ", " (keys leftover)) (join ", " (keys leftover))
@ -1821,32 +1828,33 @@
x)) x))
(defn- format-in [in [x y]] (defn- format-in [in [x y]]
(let [[sql-x & params-x] (format-expr x {:nested true}) (let [{:keys [caching checking numbered]} *options*
[sql-x & params-x] (format-expr x {:nested true})
[sql-y & params-y] (format-expr y {:nested true}) [sql-y & params-y] (format-expr y {:nested true})
[v1 :as values] (map #(unwrap % {}) params-y)] [v1 :as values] (map #(unwrap % {}) params-y)]
;; #396: prevent caching IN () when named parameter is used: ;; #396: prevent caching IN () when named parameter is used:
(when (and (meta (first params-y)) (when (and (meta (first params-y))
(::wrapper (meta (first params-y))) (::wrapper (meta (first params-y)))
*caching*) caching)
(throw (ex-info "SQL that includes IN () expressions cannot be cached" {}))) (throw (ex-info "SQL that includes IN () expressions cannot be cached" {})))
(when-not (= :none *checking*) (when-not (= :none checking)
(when (or (and (sequential? y) (empty? y)) (when (or (and (sequential? y) (empty? y))
(and (sequential? v1) (empty? v1))) (and (sequential? v1) (empty? v1)))
(throw (ex-info "IN () empty collection is illegal" (throw (ex-info "IN () empty collection is illegal"
{:clause [in x y]}))) {:clause [in x y]})))
(when (and (= :strict *checking*) (when (and (= :strict checking)
(or (and (sequential? y) (some nil? y)) (or (and (sequential? y) (some nil? y))
(and (sequential? v1) (some nil? v1)))) (and (sequential? v1) (some nil? v1))))
(throw (ex-info "IN (NULL) does not match" (throw (ex-info "IN (NULL) does not match"
{:clause [in x y]})))) {:clause [in x y]}))))
(cond (and (not *numbered*) (cond (and (not numbered)
(= "?" sql-y) (= "?" sql-y)
(= 1 (count params-y)) (= 1 (count params-y))
(coll? v1)) (coll? v1))
(let [sql (str "(" (join ", " (repeat (count v1) "?")) ")")] (let [sql (str "(" (join ", " (repeat (count v1) "?")) ")")]
(into* [(str sql-x " " (sql-kw in) " " sql)] params-x v1)) (into* [(str sql-x " " (sql-kw in) " " sql)] params-x v1))
(and *numbered* (and numbered
(= (str "$" (count @*numbered*)) sql-y) (= (str "$" (count @numbered)) sql-y)
(= 1 (count params-y)) (= 1 (count params-y))
(coll? v1)) (coll? v1))
(let [vs (for [v v1] (->numbered v)) (let [vs (for [v v1] (->numbered v))
@ -1855,7 +1863,7 @@
params-x [nil] (map second vs))) params-x [nil] (map second vs)))
:else :else
(into* [(str sql-x " " (sql-kw in) " " sql-y)] (into* [(str sql-x " " (sql-kw in) " " sql-y)]
params-x (if *numbered* values params-y))))) params-x (if numbered values params-y)))))
(defn- function-0 [k xs] (defn- function-0 [k xs]
[(str (sql-kw k) [(str (sql-kw k)
@ -2025,7 +2033,7 @@
(fn [_ [expr tz]] (fn [_ [expr tz]]
(let [[sql & params] (format-expr expr {:nested true}) (let [[sql & params] (format-expr expr {:nested true})
[tz-sql & _] [tz-sql & _]
(binding [*inline* true] (binding [*options* (assoc *options* :inline true)]
(format-expr (if (ident? tz) (name tz) tz)))] (format-expr (if (ident? tz) (name tz) tz)))]
(into [(str sql " AT TIME ZONE " tz-sql)] params))) (into [(str sql " AT TIME ZONE " tz-sql)] params)))
:between #'between-fn :between #'between-fn
@ -2057,7 +2065,7 @@
:ignore-nulls ignore-respect-nulls :ignore-nulls ignore-respect-nulls
:inline :inline
(fn [_ xs] (fn [_ xs]
(binding [*inline* true] (binding [*options* (assoc *options* :inline true)]
[(join " " (mapcat #(format-expr % {:record true})) xs)])) [(join " " (mapcat #(format-expr % {:record true})) xs)]))
:interval format-interval :interval format-interval
:join :join
@ -2074,12 +2082,12 @@
(into [(str "LATERAL " sql)] params)))) (into [(str "LATERAL " sql)] params))))
:lift :lift
(fn [_ [x]] (fn [_ [x]]
(cond *inline* (cond (:inline *options*)
;; this is pretty much always going to be wrong, ;; this is pretty much always going to be wrong,
;; but it could produce a valid result so we just ;; but it could produce a valid result so we just
;; assume that the user knows what they are doing: ;; assume that the user knows what they are doing:
[(sqlize-value x)] [(sqlize-value x)]
*numbered* (:numbered *options*)
(->numbered x) (->numbered x)
:else :else
["?" (with-meta (constantly x) ["?" (with-meta (constantly x)
@ -2116,9 +2124,9 @@
:param :param
(fn [_ [k]] (fn [_ [k]]
(let [k (sym->kw k)] (let [k (sym->kw k)]
(cond *inline* (cond (:inline *options*)
[(sqlize-value (param-value k))] [(sqlize-value (param-value k))]
*numbered* (:numbered *options*)
(->numbered-param k) (->numbered-param k)
:else :else
["?" (->param k)]))) ["?" (->param k)])))
@ -2231,9 +2239,9 @@
["NULL"] ["NULL"]
:else :else
(cond *inline* (cond (:inline *options*)
[(sqlize-value expr)] [(sqlize-value expr)]
*numbered* (:numbered *options*)
(->numbered expr) (->numbered expr)
:else :else
["?" expr])))) ["?" expr]))))
@ -2283,50 +2291,37 @@
dialect (if dialect? dialect (if dialect?
(get @dialects (check-dialect (:dialect opts))) (get @dialects (check-dialect (:dialect opts)))
@default-dialect) @default-dialect)
numbered (if (contains? opts :numbered) numbered? (:numbered opts @default-numbered)
(:numbered opts) formatter (if (map? data) #'format-dsl #'format-expr)
@default-numbered) options {:caching cache
formatter (if (map? data) #'format-dsl #'format-expr)] :checking (:checking opts @default-checking)
(binding [*dialect* dialect :clause-order (if dialect?
*caching* cache (if-let [f (:clause-order-fn dialect)]
*checking* (if (contains? opts :checking) (f @base-clause-order)
(:checking opts) @current-clause-order)
@default-checking)
*clause-order* (if dialect?
(if-let [f (:clause-order-fn dialect)]
(f @base-clause-order)
@current-clause-order) @current-clause-order)
@current-clause-order) :ignored-metadata (:ignored-metadata opts [])
*ignored-metadata* (if (contains? opts :ignored-metadata) :inline (:inline opts (if (= :nrql (:dialect dialect))
(:ignored-metadata opts) true
[]) @default-inline))
*inline* (cond (contains? opts :inline) :numbered (when numbered? (atom []))
(:inline opts) :quoted (cond (contains? opts :quoted)
(= :nrql (:dialect dialect)) (:quoted opts)
true (= :nrql (:dialect dialect))
:else nil
@default-inline) dialect?
*numbered* (when numbered true
(atom [])) :else
*quoted* (cond (contains? opts :quoted) @default-quoted)
(:quoted opts) :quoted-always (:quoted-always opts @default-quoted-always)
(= :nrql (:dialect dialect)) :quoted-snake (:quoted-snake opts @default-quoted-snake)
nil :params (reduce-kv (fn [m k v]
dialect? (assoc m (sym->kw k) v))
true {}
:else (:params opts))
@default-quoted) :values-default-columns (:values-default-columns opts)}]
*quoted-always* (if (contains? opts :quoted-always) (binding [*dialect* dialect
(:quoted-always opts) *options* options]
@default-quoted-always)
*quoted-snake* (if (contains? opts :quoted-snake)
(:quoted-snake opts)
@default-quoted-snake)
*params* (reduce-kv (fn [m k v]
(assoc m (sym->kw k) v))
{}
(:params opts))
*values-default-columns* (:values-default-columns opts)]
(if cache (if cache
(->> (through-opts opts cache data (fn [_] (formatter data (dissoc opts :cache)))) (->> (through-opts opts cache data (fn [_] (formatter data (dissoc opts :cache))))
(mapv #(unwrap % opts))) (mapv #(unwrap % opts)))