Address #121 by adding conditional builders/options for CSK

This commit is contained in:
Sean Corfield 2020-07-08 11:52:22 -07:00
parent 5e38494d8b
commit 931023de09
6 changed files with 80 additions and 5 deletions

View file

@ -32,7 +32,9 @@
org.apache.logging.log4j/log4j-1.2-api {:mvn/version "2.13.3"}
org.apache.logging.log4j/log4j-jcl {:mvn/version "2.13.3"}
org.apache.logging.log4j/log4j-jul {:mvn/version "2.13.3"}
org.apache.logging.log4j/log4j-slf4j-impl {:mvn/version "2.13.3"}}
org.apache.logging.log4j/log4j-slf4j-impl {:mvn/version "2.13.3"}
;; test auto-added snake/kebab builders and options
camel-snake-kebab {:mvn/version "0.4.1"}}
:jvm-opts ["-Dlog4j2.configurationFile=log4j2-info.properties"]}
:runner
{:extra-deps {com.cognitect/test-runner

View file

@ -279,3 +279,26 @@
wrapper object that can be used in its place."
[connectable opts]
(opts/->DefaultOptions connectable opts))
(defmacro ^:private def-snake-kebab []
(try
(let [kebab-case (requiring-resolve 'camel-snake-kebab.core/->kebab-case)
snake-case (requiring-resolve 'camel-snake-kebab.core/->snake_case)]
`(do
(def snake-kebab-opts
"A hash map of options that will convert Clojure identifiers to
snake_case SQL entities (`:table-fn`, `:column-fn`), and will convert
SQL entities to qualified kebab-case Clojure identifiers (`:builder-fn`)."
{:column-fn ~snake-case :table-fn ~snake-case
:label-fn ~kebab-case :qualifier-fn ~kebab-case
:builder-fn (resolve 'next.jdbc.result-set/as-kebab-maps)})
(def unqualified-snake-kebab-opts
"A hash map of options that will convert Clojure identifiers to
snake_case SQL entities (`:table-fn`, `:column-fn`), and will convert
SQL entities to unqualified kebab-case Clojure identifiers (`:builder-fn`)."
{:column-fn ~snake-case :table-fn ~snake-case
:label-fn ~kebab-case :qualifier-fn ~kebab-case
:builder-fn (resolve 'next.jdbc.result-set/as-unqualified-kebab-maps)})))
(catch Throwable _)))
(def-snake-kebab)

View file

@ -256,6 +256,27 @@
[rs opts]
(as-unqualified-modified-maps rs (assoc opts :label-fn lower-case)))
(defmacro ^:private def-snake-kebab []
(try
(let [kebab-case (requiring-resolve 'camel-snake-kebab.core/->kebab-case)]
`(do
(defn ~'as-kebab-maps
{:doc "Given a `ResultSet` and options, return a `RowBuilder` / `ResultSetBuilder`
that produces bare vectors of hash map rows, with kebab-case keys."
:arglists '([~'rs ~'opts])}
[rs# opts#]
(as-modified-maps rs# (assoc opts#
:qualifier-fn ~kebab-case
:label-fn ~kebab-case)))
(defn ~'as-unqualified-kebab-maps
{:doc "Given a `ResultSet` and options, return a `RowBuilder` / `ResultSetBuilder`
that produces bare vectors of hash map rows, with simple, kebab-case keys."
:arglists '([~'rs ~'opts])}
[rs# opts#]
(as-unqualified-modified-maps rs# (assoc opts# :label-fn ~kebab-case)))))
(catch Throwable _)))
(def-snake-kebab)
(defn as-maps-adapter
"Given a map builder function (e.g., `as-lower-maps`) and a column reading
function, return a new builder function that uses that column reading

View file

@ -134,6 +134,25 @@
(is (map? row))
(is (= 4 (:id row)))
(is (= "Orange" (:name row)))))
(testing "kebab-case row builder"
(let [row (p/-execute-one (ds)
["select id,name,appearance as looks_like from fruit where id = ?" 3]
(assoc (default-options)
:builder-fn rs/as-kebab-maps))]
(is (map? row))
(is (contains? row :fruit/looks-like))
(is (nil? (:fruit/looks-like row)))
(is (= 3 (:fruit/id row)))
(is (= "Peach" (:fruit/name row)))))
(testing "unqualified kebab-case row builder"
(let [row (p/-execute-one (ds)
["select id,name,appearance as looks_like from fruit where id = ?" 4]
{:builder-fn rs/as-unqualified-kebab-maps})]
(is (map? row))
(is (contains? row :looks-like))
(is (= "juicy" (:looks-like row)))
(is (= 4 (:id row)))
(is (= "Orange" (:name row)))))
(testing "custom row builder 1"
(let [row (p/-execute-one (ds)
["select fruit.*, id + 100 as newid from fruit where id = ?" 3]

View file

@ -8,7 +8,6 @@
[next.jdbc.sql :as sql]
[next.jdbc.test-fixtures
:refer [with-test-db ds column default-options
db
derby? jtds? maria? mssql? mysql? postgres? sqlite?]]
[next.jdbc.types :refer [as-other as-real as-varchar]]))
@ -183,5 +182,6 @@
(deftest enum-pg
(when (postgres?)
(let [r (sql/insert! (ds) :lang_test {:lang (as-other "fr")})]
(is (= {:lang_test/lang "fr"} r)))))
(let [r (sql/insert! (ds) :lang-test {:lang (as-other "fr")}
jdbc/snake-kebab-opts)]
(is (= {:lang-test/lang "fr"} r)))))

View file

@ -46,7 +46,17 @@
(is (= "Apple" ((column :FRUIT/NAME)
(jdbc/execute-one!
ds-opts
["select * from fruit where appearance = ?" "red"])))))
["select * from fruit where appearance = ?" "red"]))))
(is (= "red" (:fruit/looks-like
(jdbc/execute-one!
ds-opts
["select appearance as looks_like from fruit where id = ?" 1]
jdbc/snake-kebab-opts))))
(is (= "red" (:looks-like
(jdbc/execute-one!
ds-opts
["select appearance as looks_like from fruit where id = ?" 1]
jdbc/unqualified-snake-kebab-opts)))))
(testing "execute!"
(let [rs (jdbc/execute!
ds-opts