From d6fe4c15777080b1ee25f0da6ec8d30345f92303 Mon Sep 17 00:00:00 2001 From: Sean Corfield Date: Fri, 10 Nov 2023 13:26:21 -0800 Subject: [PATCH] fix #264 --- CHANGELOG.md | 1 + doc/getting-started.md | 5 +++++ src/next/jdbc/specs.clj | 12 +++++------- src/next/jdbc/sql.clj | 6 ++++-- test/next/jdbc/sql_test.clj | 20 +++++++++++++++++--- 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2289bdc..527c5d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Only accretive/fixative changes will be made from now on. * 1.3.next in progress + * Address [#264](https://github.com/seancorfield/next-jdbc/issues/264) by letting `insert-multi!` accept empty rows (and producing an empty result vector). This improves compatibility with `clojure.javaj.jdbc`. * Address [#258](https://github.com/seancorfield/next-jdbc/issues/258) by updating all the library (driver) versions in Getting Started to match the latest versions being tested (from `deps.edn`). * Expand examples for calling `next.jdbc.sql/find-by-keys` to show `LIKE` and `IN` clauses. * Update `tools.build` to 0.9.6 (and get rid of `template/pom.xml` in favor of new `:pom-data` option to `b/write-pom`). diff --git a/doc/getting-started.md b/doc/getting-started.md index 95d552c..fe8737b 100644 --- a/doc/getting-started.md +++ b/doc/getting-started.md @@ -77,6 +77,11 @@ We described the database with just `:dbtype` and `:dbname` because it is create > Note: You can see the full list of `:dbtype` values supported in [next.jdbc/get-datasource](https://cljdoc.org/d/com.github.seancorfield/next.jdbc/CURRENT/api/next.jdbc#get-datasource)'s docstring. If you need this programmatically, you can get it from the [next.jdbc.connection/dbtypes](https://cljdoc.org/d/com.github.seancorfield/next.jdbc/CURRENT/api/next.jdbc.connection#dbtypes) hash map. If those lists differ, the hash map is the definitive list (and I'll need to fix the docstring!). The docstring of that Var explains how to tell `next.jdbc` about additional databases. +The hash map can contain arbitrary keys and values: any keys not specifically +recognized by `next.jdbc` will be passed through to the JDBC driver as part +of the connection string. For example, if you specify `:useSSL false`, then +the connection string will have `&useSSL=false` appended to it. + If you already have a JDBC URL (string), you can use that as-is instead of the db-spec hash map. If you have a JDBC URL and still need additional options passed into the JDBC driver, you can use a hash map with the `:jdbcUrl` key specifying the string and whatever additional options you need. ### `execute!` & `execute-one!` diff --git a/src/next/jdbc/specs.clj b/src/next/jdbc/specs.clj index 1c269c9..e1cd0e1 100644 --- a/src/next/jdbc/specs.clj +++ b/src/next/jdbc/specs.clj @@ -205,10 +205,10 @@ :with-rows-and-columns (s/and (s/cat :connectable ::connectable :table keyword? - :cols (s/coll-of keyword? - :kind sequential? - :min-count 1) - :rows (s/coll-of (s/coll-of any? :kind sequential?) + :cols (s/coll-of keyword? :kind sequential?) + :rows (s/coll-of (s/coll-of any? + :kind sequential? + :min-count 1) :kind sequential?) :opts (s/? ::opts-map)) #(apply = (count (:cols %)) @@ -216,9 +216,7 @@ :with-hash-maps (s/cat :connectable ::connectable :table keyword? - :hash-maps (s/coll-of map? - :kind sequential? - :min-count 1) + :hash-maps (s/coll-of map? :kind sequential?) :opts (s/? ::opts-map)))) (s/fdef sql/query diff --git a/src/next/jdbc/sql.clj b/src/next/jdbc/sql.clj index bd40873..940ca4b 100644 --- a/src/next/jdbc/sql.clj +++ b/src/next/jdbc/sql.clj @@ -1,4 +1,4 @@ -;; copyright (c) 2019-2022 Sean Corfield, all rights reserved +;; copyright (c) 2019-2023 Sean Corfield, all rights reserved (ns next.jdbc.sql "Some utility functions that make common operations easier by @@ -78,7 +78,9 @@ (throw (IllegalArgumentException. "insert-multi! hash maps must all have the same keys"))) (insert-multi! connectable table cols (map ->row hash-maps-or-cols) opts-or-rows)) - (insert-multi! connectable table hash-maps-or-cols opts-or-rows {}))) + (if (map? opts-or-rows) + (insert-multi! connectable table hash-maps-or-cols [] opts-or-rows) + (insert-multi! connectable table hash-maps-or-cols opts-or-rows {})))) ([connectable table cols rows opts] (if (seq rows) (let [opts (merge (:options connectable) opts) diff --git a/test/next/jdbc/sql_test.clj b/test/next/jdbc/sql_test.clj index ec4e687..6841566 100644 --- a/test/next/jdbc/sql_test.clj +++ b/test/next/jdbc/sql_test.clj @@ -1,4 +1,4 @@ -;; copyright (c) 2019-2021 Sean Corfield, all rights reserved +;; copyright (c) 2019-2023 Sean Corfield, all rights reserved (ns next.jdbc.sql-test "Tests for the syntactic sugar SQL functions." @@ -193,13 +193,27 @@ (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 and #264 (is (= [] (sql/insert-multi! (ds) :fruit [:name :appearance :cost :grade] [] {:suffix (when (sqlite?) - "RETURNING *")})))))) + "RETURNING *")}))) + ;; per #264 the following should all be legal too: + (is (= [] (sql/insert-multi! (ds) :fruit + [] + {:suffix + (when (sqlite?) + "RETURNING *")}))) + (is (= [] (sql/insert-multi! (ds) :fruit + [] + [] + {:suffix + (when (sqlite?) + "RETURNING *")}))) + (is (= [] (sql/insert-multi! (ds) :fruit []))) + (is (= [] (sql/insert-multi! (ds) :fruit [] [])))))) (deftest no-empty-example-maps (is (thrown? clojure.lang.ExceptionInfo