Flesh out more SQL generators
Add high-level insert!, insert-multi!, update!, delete! Add more examples to tests.
This commit is contained in:
parent
561ccfc621
commit
8646472e79
3 changed files with 107 additions and 6 deletions
|
|
@ -6,6 +6,7 @@
|
|||
[next.jdbc.prepare :as prepare] ; used to extend protocols
|
||||
[next.jdbc.protocols :as p]
|
||||
[next.jdbc.result-set :as rs]
|
||||
[next.jdbc.sql :as sql]
|
||||
[next.jdbc.transaction])) ; used to extend protocols
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
|
@ -45,3 +46,55 @@
|
|||
(defmacro with-transaction
|
||||
[[sym connectable opts] & body]
|
||||
`(p/-transact ~connectable (fn [~sym] ~@body) ~opts))
|
||||
|
||||
(defn insert!
|
||||
""
|
||||
([connectable table key-map]
|
||||
(rs/execute! connectable
|
||||
(sql/for-insert table key-map {})
|
||||
{:return-keys true}))
|
||||
([connectable table key-map opts]
|
||||
(rs/execute! connectable
|
||||
(sql/for-insert table key-map opts)
|
||||
(merge {:return-keys true} opts))))
|
||||
|
||||
(defn insert-multi!
|
||||
""
|
||||
([connectable table cols rows]
|
||||
(rs/execute! connectable
|
||||
(sql/for-insert-multi table cols rows {})
|
||||
{:return-keys true}))
|
||||
([connectable table cols rows opts]
|
||||
(rs/execute! connectable
|
||||
(sql/for-insert-multi table cols rows opts)
|
||||
(merge {:return-keys true} opts))))
|
||||
|
||||
(defn find-by-keys
|
||||
""
|
||||
([connectable table key-map]
|
||||
(rs/execute! connectable (sql/for-query table key-map {}) {}))
|
||||
([connectable table key-map opts]
|
||||
(rs/execute! connectable (sql/for-query table key-map opts) opts)))
|
||||
|
||||
(defn get-by-id
|
||||
""
|
||||
([connectable table pk]
|
||||
(rs/execute-one! connectable (sql/for-query table {:id pk} {}) {}))
|
||||
([connectable table pk opts]
|
||||
(rs/execute-one! connectable (sql/for-query table {:id pk} opts) opts))
|
||||
([connectable table pk pk-name opts]
|
||||
(rs/execute-one! connectable (sql/for-query table {pk-name pk} opts) opts)))
|
||||
|
||||
(defn update!
|
||||
""
|
||||
([connectable table key-map where-params]
|
||||
(rs/execute! connectable (sql/for-update table key-map where-params {}) {}))
|
||||
([connectable table key-map where-params opts]
|
||||
(rs/execute! connectable (sql/for-update table key-map where-params opts) opts)))
|
||||
|
||||
(defn delete!
|
||||
""
|
||||
([connectable table where-params]
|
||||
(rs/execute! connectable (sql/for-delete table where-params {}) {}))
|
||||
([connectable table where-params opts]
|
||||
(rs/execute! connectable (sql/for-delete table where-params opts) opts)))
|
||||
|
|
|
|||
|
|
@ -36,13 +36,28 @@
|
|||
|
||||
(defn for-query
|
||||
""
|
||||
[table key-map opts]
|
||||
[table where-params opts]
|
||||
(let [entity-fn (:entities opts identity)
|
||||
where-params (by-keys key-map :where opts)]
|
||||
where-params (if (map? where-params)
|
||||
(by-keys where-params :where opts)
|
||||
(into [(str "WHERE " (first where-params))]
|
||||
(rest where-params)))]
|
||||
(into [(str "SELECT * FROM " (entity-fn (name table))
|
||||
" " (first where-params))]
|
||||
(rest where-params))))
|
||||
|
||||
(defn for-delete
|
||||
""
|
||||
[table where-params opts]
|
||||
(let [entity-fn (:entities opts identity)
|
||||
where-params (if (map? where-params)
|
||||
(by-keys where-params :where opts)
|
||||
(into [(str "WHERE " (first where-params))]
|
||||
(rest where-params)))]
|
||||
(into [(str "DELETE FROM " (entity-fn (name table))
|
||||
" " (first where-params))]
|
||||
(rest where-params))))
|
||||
|
||||
(defn for-update
|
||||
""
|
||||
[table key-map where-params opts]
|
||||
|
|
@ -69,13 +84,36 @@
|
|||
" VALUES (" places ")")]
|
||||
(vals key-map))))
|
||||
|
||||
(defn for-insert-multi
|
||||
""
|
||||
[table cols rows opts]
|
||||
(assert (apply = (count cols) (map count rows)))
|
||||
(let [entity-fn (:entities opts identity)
|
||||
params (str/join ", " (map (comp entity-fn name) cols))
|
||||
places (as-? (first rows) opts)]
|
||||
(into [(str "INSERT INTO " (entity-fn (name table))
|
||||
" (" params ")"
|
||||
" VALUES "
|
||||
(str/join ", " (repeat (count rows) (str "(" places ")"))))]
|
||||
cat
|
||||
rows)))
|
||||
|
||||
(comment
|
||||
(require '[next.jdbc.quoted :refer [mysql]])
|
||||
(by-keys {:a nil :b 42 :c "s"} {})
|
||||
(by-keys {:a nil :b 42 :c "s"} :where {})
|
||||
(as-keys {:a nil :b 42 :c "s"} {})
|
||||
(as-? {:a nil :b 42 :c "s"} {})
|
||||
(for-query :user {:id 9} {:entities mysql})
|
||||
(for-query :user {:id nil} {:entities mysql})
|
||||
(for-query :user ["id = ? and opt is null" 9] {:entities mysql})
|
||||
(for-delete :user {:opt nil :id 9} {:entities mysql})
|
||||
(for-delete :user ["id = ? and opt is null" 9] {:entities mysql})
|
||||
(for-update :user {:status 42} {} {:entities mysql})
|
||||
(for-update :user {:status 42} {:id 9} {:entities mysql})
|
||||
(for-update :user {:status 42} ["id = ?" 9] {:entities mysql})
|
||||
(for-insert :user {:id 9 :status 42 :opt nil} {:entities mysql}))
|
||||
(for-update :user {:status 42, :opt nil} ["id = ?" 9] {:entities mysql})
|
||||
(for-insert :user {:id 9 :status 42 :opt nil} {:entities mysql})
|
||||
(for-insert-multi :user [:id :status]
|
||||
[[42 "hello"]
|
||||
[35 "world"]
|
||||
[64 "dollars"]]
|
||||
{:entities mysql}))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
(ns next.jdbc-test
|
||||
(:require [clojure.test :refer [deftest is testing]]
|
||||
[next.jdbc :refer :all]))
|
||||
[next.jdbc :refer :all]
|
||||
[next.jdbc.result-set :as rs]))
|
||||
|
||||
(deftest a-test
|
||||
(testing "FIXME, I fail."
|
||||
|
|
@ -19,6 +20,12 @@
|
|||
;; h2
|
||||
(execute! con ["CREATE TABLE fruit (id int default 0, name varchar(32) primary key, appearance varchar(32), cost int, grade real)"])
|
||||
(execute! con ["INSERT INTO fruit (id,name,appearance,cost,grade) VALUES (1,'Apple','red',59,87), (2,'Banana','yellow',29,92.2), (3,'Peach','fuzzy',139,90.0), (4,'Orange','juicy',89,88.6)"])
|
||||
(insert-multi! con :fruit [:id :name :appearance :cost :grade]
|
||||
[[1 "Apple" "red" 59 87]
|
||||
[2,"Banana","yellow",29,92.2]
|
||||
[3,"Peach","fuzzy",139,90.0]
|
||||
[4,"Orange","juicy",89,88.6]]
|
||||
{:return-keys false})
|
||||
;; mysql
|
||||
(execute! con ["CREATE TABLE fruit (id int auto_increment, name varchar(32), appearance varchar(32), cost int, grade real, primary key (id))"])
|
||||
(execute! con ["INSERT INTO fruit (id,name,appearance,cost,grade) VALUES (1,'Apple','red',59,87), (2,'Banana','yellow',29,92.2), (3,'Peach','fuzzy',139,90.0), (4,'Orange','juicy',89,88.6)"]
|
||||
|
|
@ -58,6 +65,7 @@
|
|||
|
||||
(execute! con ["select * from fruit"])
|
||||
(into [] (map (partial into {})) (reducible! con ["select * from fruit"]))
|
||||
(into [] (map (rs/datafiable-row con {})) (reducible! con ["select * from fruit"]))
|
||||
|
||||
;; with a prepopulated prepared statement
|
||||
(with-open [ps (prepare con ["select * from fruit where appearance = ?" "red"] {})]
|
||||
|
|
@ -101,5 +109,7 @@
|
|||
(execute! t ["INSERT INTO fruit (id,name,appearance,cost,grade) VALUES (5,'Pear','green',49,47)"])
|
||||
(execute! t ["select * from fruit where name = ?" "Pear"]))
|
||||
(execute! con ["select * from fruit where name = ?" "Pear"])
|
||||
(delete! con :fruit {:id 1})
|
||||
|
||||
(update! con :fruit {:appearance "Brown"} {:name "Banana"})
|
||||
(execute! con ["select * from membership"]))
|
||||
|
|
|
|||
Loading…
Reference in a new issue