parent
737699c11a
commit
3073d28525
3 changed files with 84 additions and 49 deletions
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
* 2.3.next in progress
|
||||
* Address [#425](https://github.com/seancorfield/honeysql/issues/425) by clarifying that `INTERVAL` as special syntax may be MySQL-specific and PostgreSQL uses difference syntax (because `INTERVAL` is a data type there).
|
||||
* Address [#423](https://github.com/seancorfield/honeysql/issues/423) by supporting `DEFAULT` values and `DEFAULT` rows in `VALUES` clause -- NEEDS DOCUMENTATION!
|
||||
* **WIP** Address [#422](https://github.com/seancorfield/honeysql/issues/422) by auto-quoting unusual entity names when `:quoted` (and `:dialect`) are not specified, making HoneySQL more secure by default.
|
||||
* Address [#419](https://github.com/seancorfield/honeysql/issues/419) by adding `honey.sql.protocols` and `InlineValue` with a `sqlize` function.
|
||||
* Address [#413](https://github.com/seancorfield/honeysql/issues/413) by flagging a lack of `WHERE` clause for `DELETE`, `DELETE FROM`, and `UPDATE` when `:checking :basic` (or `:checking :strict`).
|
||||
|
|
|
|||
|
|
@ -699,59 +699,74 @@
|
|||
(str " " (sql-kw nowait))))))]))
|
||||
|
||||
(defn- format-values [k xs]
|
||||
(cond (sequential? (first xs))
|
||||
;; [[1 2 3] [4 5 6]]
|
||||
(let [n-1 (map count xs)
|
||||
;; issue #291: ensure all value sequences are the same length
|
||||
xs' (if (apply = n-1)
|
||||
xs
|
||||
(let [n-n (apply max n-1)]
|
||||
(map (fn [x] (take n-n (concat x (repeat nil)))) xs)))
|
||||
[sqls params]
|
||||
(reduce (fn [[sql params] [sqls' params']]
|
||||
[(conj sql (str "(" (str/join ", " sqls') ")"))
|
||||
(into params params')])
|
||||
[[] []]
|
||||
(map #'format-expr-list xs'))]
|
||||
(into [(str (sql-kw k) " " (str/join ", " sqls))] params))
|
||||
(let [first-xs (when (sequential? xs) (first (drop-while ident? xs)))]
|
||||
(cond (contains? #{:default 'default} xs)
|
||||
[(str (sql-kw xs) " " (sql-kw k))]
|
||||
(empty? xs)
|
||||
[(str (sql-kw k) " ()")]
|
||||
(sequential? first-xs)
|
||||
;; [[1 2 3] [4 5 6]]
|
||||
(let [n-1 (map count (filter sequential? xs))
|
||||
;; issue #291: ensure all value sequences are the same length
|
||||
xs' (if (apply = n-1)
|
||||
xs
|
||||
(let [n-n (when (seq n-1) (apply max n-1))]
|
||||
(map (fn [x]
|
||||
(if (sequential? x)
|
||||
(take n-n (concat x (repeat nil)))
|
||||
x))
|
||||
xs)))
|
||||
[sqls params]
|
||||
(reduce (fn [[sql params] [sqls' params']]
|
||||
[(conj sql
|
||||
(if (sequential? sqls')
|
||||
(str "(" (str/join ", " sqls') ")")
|
||||
sqls'))
|
||||
(into params params')])
|
||||
[[] []]
|
||||
(map #(if (sequential? %)
|
||||
(format-expr-list %)
|
||||
[(sql-kw %)])
|
||||
xs'))]
|
||||
(into [(str (sql-kw k) " " (str/join ", " sqls))] params))
|
||||
|
||||
(map? (first xs))
|
||||
;; [{:a 1 :b 2 :c 3}]
|
||||
(let [cols-1 (keys (first xs))
|
||||
;; issue #291: check for all keys in all maps but still
|
||||
;; use the keys from the first map if they match so that
|
||||
;; users can rely on the key ordering if they want to,
|
||||
;; e.g., see test that uses array-map for the first row
|
||||
cols-n (into #{} (mapcat keys) xs)
|
||||
cols (if (= (set cols-1) cols-n) cols-1 cols-n)
|
||||
[sqls params]
|
||||
(reduce (fn [[sql params] [sqls' params']]
|
||||
[(conj sql (str "(" (str/join ", " sqls') ")"))
|
||||
(if params' (into params params') params')])
|
||||
[[] []]
|
||||
(map (fn [m]
|
||||
(format-expr-list
|
||||
(map #(get m
|
||||
%
|
||||
(map? first-xs)
|
||||
;; [{:a 1 :b 2 :c 3}]
|
||||
(let [cols-1 (keys (first xs))
|
||||
;; issue #291: check for all keys in all maps but still
|
||||
;; use the keys from the first map if they match so that
|
||||
;; users can rely on the key ordering if they want to,
|
||||
;; e.g., see test that uses array-map for the first row
|
||||
cols-n (into #{} (mapcat keys) xs)
|
||||
cols (if (= (set cols-1) cols-n) cols-1 cols-n)
|
||||
[sqls params]
|
||||
(reduce (fn [[sql params] [sqls' params']]
|
||||
[(conj sql (str "(" (str/join ", " sqls') ")"))
|
||||
(if params' (into params params') params')])
|
||||
[[] []]
|
||||
(map (fn [m]
|
||||
(format-expr-list
|
||||
(map #(get m
|
||||
%
|
||||
;; issue #366: use NULL or DEFAULT
|
||||
;; for missing column values:
|
||||
(if (contains? *values-default-columns* %)
|
||||
[:default]
|
||||
nil))
|
||||
cols)))
|
||||
xs))]
|
||||
(into [(str "("
|
||||
(str/join ", "
|
||||
(map #(format-entity % {:drop-ns true}) cols))
|
||||
") "
|
||||
(sql-kw k)
|
||||
" "
|
||||
(str/join ", " sqls))]
|
||||
params))
|
||||
(if (contains? *values-default-columns* %)
|
||||
[:default]
|
||||
nil))
|
||||
cols)))
|
||||
xs))]
|
||||
(into [(str "("
|
||||
(str/join ", "
|
||||
(map #(format-entity % {:drop-ns true}) cols))
|
||||
") "
|
||||
(sql-kw k)
|
||||
" "
|
||||
(str/join ", " sqls))]
|
||||
params))
|
||||
|
||||
:else
|
||||
(throw (ex-info ":values expects sequences or maps"
|
||||
{:first (first xs)}))))
|
||||
:else
|
||||
(throw (ex-info ":values expects sequences or maps"
|
||||
{:first (first xs)})))))
|
||||
|
||||
(comment
|
||||
(into #{} (mapcat keys) [{:a 1 :b 2} {:b 3 :c 4}])
|
||||
|
|
|
|||
|
|
@ -737,6 +737,25 @@ ORDER BY id = ? DESC
|
|||
:values [{:name name
|
||||
:enabled enabled}]})))))
|
||||
|
||||
(deftest issue-425-default-values-test
|
||||
(testing "default values"
|
||||
(is (= ["INSERT INTO table (a, b, c) DEFAULT VALUES"]
|
||||
(format {:insert-into [:table [:a :b :c]] :values :default}))))
|
||||
(testing "values with default row"
|
||||
(is (= ["INSERT INTO table (a, b, c) VALUES (1, 2, 3), DEFAULT, (4, 5, 6)"]
|
||||
(format {:insert-into [:table [:a :b :c]]
|
||||
:values [[1 2 3] :default [4 5 6]]}
|
||||
{:inline true}))))
|
||||
(testing "values with default column"
|
||||
(is (= ["INSERT INTO table (a, b, c) VALUES (1, DEFAULT, 3), DEFAULT"]
|
||||
(format {:insert-into [:table [:a :b :c]]
|
||||
:values [[1 [:default] 3] :default]}
|
||||
{:inline true}))))
|
||||
(testing "empty values"
|
||||
(is (= ["INSERT INTO table (a, b, c) VALUES ()"]
|
||||
(format {:insert-into [:table [:a :b :c]]
|
||||
:values []})))))
|
||||
|
||||
(deftest issue-316-test
|
||||
;; this is a pretty naive test -- there are other tricks to perform injection
|
||||
;; that are not detected by HoneySQL and you should generally use :quoted true
|
||||
|
|
|
|||
Loading…
Reference in a new issue