feat: insert hashmaps with sql.insert-multi!
Updates the API of `sql/insert-multi!` to support sequences of hash maps which will automatically be converted into rows and columns.
This commit is contained in:
parent
1d0abe2286
commit
0531ae0268
3 changed files with 66 additions and 12 deletions
|
|
@ -180,16 +180,26 @@
|
||||||
:opts (s/? ::opts-map)))
|
:opts (s/? ::opts-map)))
|
||||||
|
|
||||||
(s/fdef sql/insert-multi!
|
(s/fdef sql/insert-multi!
|
||||||
:args (s/and (s/cat :connectable ::connectable
|
:args
|
||||||
:table keyword?
|
(s/or
|
||||||
:cols (s/coll-of keyword?
|
:with-rows-and-columns
|
||||||
:kind sequential?
|
(s/and (s/cat :connectable ::connectable
|
||||||
:min-count 1)
|
:table keyword?
|
||||||
:rows (s/coll-of (s/coll-of any? :kind sequential?)
|
:cols (s/coll-of keyword?
|
||||||
:kind sequential?)
|
:kind sequential?
|
||||||
:opts (s/? ::opts-map))
|
:min-count 1)
|
||||||
#(apply = (count (:cols %))
|
:rows (s/coll-of (s/coll-of any? :kind sequential?)
|
||||||
(map count (:rows %)))))
|
:kind sequential?)
|
||||||
|
:opts (s/? ::opts-map))
|
||||||
|
#(apply = (count (:cols %))
|
||||||
|
(map count (:rows %))))
|
||||||
|
:with-hash-maps
|
||||||
|
(s/cat :connectable ::connectable
|
||||||
|
:table keyword?
|
||||||
|
:hash-maps (s/coll-of map?
|
||||||
|
:kind sequential?
|
||||||
|
:min-count 1)
|
||||||
|
:opts (s/? ::opts-map))))
|
||||||
|
|
||||||
(s/fdef sql/query
|
(s/fdef sql/query
|
||||||
:args (s/cat :connectable ::connectable
|
:args (s/cat :connectable ::connectable
|
||||||
|
|
|
||||||
|
|
@ -50,12 +50,26 @@
|
||||||
multiple rows in the database and attempts to return a vector of maps of
|
multiple rows in the database and attempts to return a vector of maps of
|
||||||
generated keys.
|
generated keys.
|
||||||
|
|
||||||
|
Also supports a sequence of hash maps with keys corresponding to column
|
||||||
|
names.
|
||||||
|
|
||||||
Note: this expands to a single SQL statement with placeholders for every
|
Note: this expands to a single SQL statement with placeholders for every
|
||||||
value being inserted -- for large sets of rows, this may exceed the limits
|
value being inserted -- for large sets of rows, this may exceed the limits
|
||||||
on SQL string size and/or number of parameters for your JDBC driver or your
|
on SQL string size and/or number of parameters for your JDBC driver or your
|
||||||
database!"
|
database!"
|
||||||
([connectable table cols rows]
|
{:arglists '([connectable table hash-maps]
|
||||||
(insert-multi! connectable table cols rows {}))
|
[connectable table hash-maps opts]
|
||||||
|
[connectable table cols rows]
|
||||||
|
[connectable table cols rows opts])}
|
||||||
|
([connectable table hash-maps]
|
||||||
|
(insert-multi! connectable table hash-maps {}))
|
||||||
|
([connectable table hash-maps-or-cols opts-or-rows]
|
||||||
|
(if-not (-> hash-maps-or-cols first map?)
|
||||||
|
(insert-multi! connectable table hash-maps-or-cols opts-or-rows {})
|
||||||
|
(let [cols (keys (first hash-maps-or-cols))
|
||||||
|
->row (fn ->row [m]
|
||||||
|
(map (partial get m) cols))]
|
||||||
|
(insert-multi! connectable table cols (map ->row hash-maps-or-cols) opts-or-rows))))
|
||||||
([connectable table cols rows opts]
|
([connectable table cols rows opts]
|
||||||
(if (seq rows)
|
(if (seq rows)
|
||||||
(let [opts (merge (:options connectable) opts)]
|
(let [opts (merge (:options connectable) opts)]
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,36 @@
|
||||||
(is (= {:next.jdbc/update-count 2}
|
(is (= {:next.jdbc/update-count 2}
|
||||||
(sql/delete! (ds) :fruit ["id > ?" 4])))
|
(sql/delete! (ds) :fruit ["id > ?" 4])))
|
||||||
(is (= 4 (count (sql/query (ds) ["select * from fruit"])))))
|
(is (= 4 (count (sql/query (ds) ["select * from fruit"])))))
|
||||||
|
(testing "multiple insert/delete with maps"
|
||||||
|
(is (= (cond (derby?)
|
||||||
|
[nil] ; WTF Apache Derby?
|
||||||
|
(mssql?)
|
||||||
|
[14M]
|
||||||
|
(sqlite?)
|
||||||
|
[14]
|
||||||
|
:else
|
||||||
|
[12 13 14])
|
||||||
|
(mapv new-key
|
||||||
|
(sql/insert-multi! (ds) :fruit
|
||||||
|
[{:name "Kiwi"
|
||||||
|
:appearance "green & fuzzy"
|
||||||
|
:cost 100
|
||||||
|
:grade 99.9}
|
||||||
|
{:name "Grape"
|
||||||
|
:appearance "black"
|
||||||
|
:cost 10
|
||||||
|
:grade 50}
|
||||||
|
{:name "Lemon"
|
||||||
|
:appearance "yellow"
|
||||||
|
:cost 20
|
||||||
|
:grade 9.9}]))))
|
||||||
|
(is (= 7 (count (sql/query (ds) ["select * from fruit"]))))
|
||||||
|
(is (= {:next.jdbc/update-count 1}
|
||||||
|
(sql/delete! (ds) :fruit {:id 12})))
|
||||||
|
(is (= 6 (count (sql/query (ds) ["select * from fruit"]))))
|
||||||
|
(is (= {:next.jdbc/update-count 2}
|
||||||
|
(sql/delete! (ds) :fruit ["id > ?" 10])))
|
||||||
|
(is (= 4 (count (sql/query (ds) ["select * from fruit"])))))
|
||||||
(testing "empty insert-multi!" ; per #44
|
(testing "empty insert-multi!" ; per #44
|
||||||
(is (= [] (sql/insert-multi! (ds) :fruit
|
(is (= [] (sql/insert-multi! (ds) :fruit
|
||||||
[:name :appearance :cost :grade]
|
[:name :appearance :cost :grade]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue