Address #2 by solidifying row function API

Low-level `execute!` requires row function to be passed. High-level API 
allows row function, else `datafiable-row`. Syntactic sugar still uses 
`:row-fn`.
This commit is contained in:
Sean Corfield 2019-04-02 00:41:39 -07:00
parent c2c9bcbba4
commit e85f627a00
3 changed files with 76 additions and 36 deletions

View file

@ -141,13 +141,18 @@
Invokes 'reducible!' and then reduces that into a vector of hash maps. Invokes 'reducible!' and then reduces that into a vector of hash maps.
Can be called on a PreparedStatement, a Connection, or something that can Can be called on a PreparedStatement, a Connection, or something that can
produce a Connection via a DataSource." produce a Connection via a DataSource.
If it is called on a PreparedStatement, it cannot produce a datafiable
result (because that requires a connectable instead)."
([stmt] ([stmt]
(rs/execute! stmt [] {})) (rs/execute! stmt [] (partial into {}) {}))
([connectable sql-params] ([connectable sql-params]
(rs/execute! connectable sql-params {})) (rs/execute! connectable sql-params (rs/datafiable-row connectable {}) {}))
([connectable sql-params opts] ([connectable sql-params opts]
(rs/execute! connectable sql-params opts))) (rs/execute! connectable sql-params (rs/datafiable-row connectable opts) opts))
([connectable sql-params f opts]
(rs/execute! connectable sql-params f opts)))
(defn execute-one! (defn execute-one!
"General SQL execution function that returns just the first row of a result. "General SQL execution function that returns just the first row of a result.
@ -155,13 +160,18 @@
Invokes 'reducible!' but immediately returns the first row. Invokes 'reducible!' but immediately returns the first row.
Can be called on a PreparedStatement, a Connection, or something that can Can be called on a PreparedStatement, a Connection, or something that can
produce a Connection via a DataSource." produce a Connection via a DataSource.
If it is called on a PreparedStatement, it cannot produce a datafiable
result (because that requires a connectable instead)."
([stmt] ([stmt]
(rs/execute-one! stmt [] {})) (rs/execute-one! stmt [] (partial into {}) {}))
([connectable sql-params] ([connectable sql-params]
(rs/execute-one! connectable sql-params {})) (rs/execute-one! connectable sql-params (rs/datafiable-row connectable {}) {}))
([connectable sql-params opts] ([connectable sql-params opts]
(rs/execute-one! connectable sql-params opts))) (rs/execute-one! connectable sql-params (rs/datafiable-row connectable opts) opts))
([connectable sql-params f opts]
(rs/execute-one! connectable sql-params f opts)))
(defn transact (defn transact
"Given a connectable object and a function (taking a Connection), "Given a connectable object and a function (taking a Connection),
@ -193,12 +203,11 @@
data as a single row in the database and attempts to return a map of generated data as a single row in the database and attempts to return a map of generated
keys." keys."
([connectable table key-map] ([connectable table key-map]
(rs/execute! connectable (insert! connectable table key-map {}))
(sql/for-insert table key-map {})
{:return-keys true}))
([connectable table key-map opts] ([connectable table key-map opts]
(rs/execute! connectable (rs/execute! connectable
(sql/for-insert table key-map opts) (sql/for-insert table key-map opts)
(partial into {})
(merge {:return-keys true} opts)))) (merge {:return-keys true} opts))))
(defn insert-multi! (defn insert-multi!
@ -209,12 +218,11 @@
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."
([connectable table cols rows] ([connectable table cols rows]
(rs/execute! connectable (insert-multi! connectable table cols rows {}))
(sql/for-insert-multi table cols rows {})
{:return-keys true}))
([connectable table cols rows opts] ([connectable table cols rows opts]
(rs/execute! connectable (rs/execute! connectable
(sql/for-insert-multi table cols rows opts) (sql/for-insert-multi table cols rows opts)
(partial into {})
(merge {:return-keys true} opts)))) (merge {:return-keys true} opts))))
(defn query (defn query
@ -223,9 +231,17 @@
Given a connectable object, and a vector of SQL and its parameters, Given a connectable object, and a vector of SQL and its parameters,
returns a vector of hash maps of rows that match." returns a vector of hash maps of rows that match."
([connectable sql-params] ([connectable sql-params]
(rs/execute! connectable sql-params {})) (query connectable sql-params {}))
([connectable sql-params opts] ([connectable sql-params opts]
(rs/execute! connectable sql-params opts))) (if-let [row-fn (:row-fn opts)]
(rs/execute! connectable
sql-params
row-fn
opts)
(rs/execute! connectable
sql-params
(rs/datafiable-row connectable opts)
opts))))
(defn find-by-keys (defn find-by-keys
"Syntactic sugar over execute! to make certain common queries easier. "Syntactic sugar over execute! to make certain common queries easier.
@ -233,9 +249,17 @@
Given a connectable object, a table name, and a hash map of columns and Given a connectable object, a table name, and a hash map of columns and
their values, returns a vector of hash maps of rows that match." their values, returns a vector of hash maps of rows that match."
([connectable table key-map] ([connectable table key-map]
(rs/execute! connectable (sql/for-query table key-map {}) {})) (find-by-keys connectable table key-map {}))
([connectable table key-map opts] ([connectable table key-map opts]
(rs/execute! connectable (sql/for-query table key-map opts) opts))) (if-let [row-fn (:row-fn opts)]
(rs/execute! connectable
(sql/for-query table key-map opts)
row-fn
opts)
(rs/execute! connectable
(sql/for-query table key-map opts)
(rs/datafiable-row connectable opts)
opts))))
(defn get-by-id (defn get-by-id
"Syntactic sugar over execute! to make certain common queries easier. "Syntactic sugar over execute! to make certain common queries easier.
@ -246,11 +270,19 @@
By default, the primary key is assumed to be 'id' but that can be overridden By default, the primary key is assumed to be 'id' but that can be overridden
in the five-argument call." in the five-argument call."
([connectable table pk] ([connectable table pk]
(rs/execute-one! connectable (sql/for-query table {:id pk} {}) {})) (get-by-id connectable table pk :id {}))
([connectable table pk opts] ([connectable table pk opts]
(rs/execute-one! connectable (sql/for-query table {:id pk} opts) opts)) (get-by-id connectable table pk :id opts))
([connectable table pk pk-name opts] ([connectable table pk pk-name opts]
(rs/execute-one! connectable (sql/for-query table {pk-name pk} opts) opts))) (if-let [row-fn (:row-fn opts)]
(rs/execute-one! connectable
(sql/for-query table {pk-name pk} opts)
row-fn
opts)
(rs/execute-one! connectable
(sql/for-query table {pk-name pk} opts)
(rs/datafiable-row connectable opts)
opts))))
(defn update! (defn update!
"Syntactic sugar over execute! to make certain common updates easier. "Syntactic sugar over execute! to make certain common updates easier.
@ -259,9 +291,12 @@
to set, and either a hash map of columns and values to search on or a vector to set, and either a hash map of columns and values to search on or a vector
of a SQL where clause and parameters, perform an update on the table." of a SQL where clause and parameters, perform an update on the table."
([connectable table key-map where-params] ([connectable table key-map where-params]
(rs/execute! connectable (sql/for-update table key-map where-params {}) {})) (update! connectable table key-map where-params {}))
([connectable table key-map where-params opts] ([connectable table key-map where-params opts]
(rs/execute! connectable (sql/for-update table key-map where-params opts) opts))) (rs/execute! connectable
(sql/for-update table key-map where-params opts)
(partial into {})
opts)))
(defn delete! (defn delete!
"Syntactic sugar over execute! to make certain common deletes easier. "Syntactic sugar over execute! to make certain common deletes easier.
@ -270,6 +305,9 @@
and values to search on or a vector of a SQL where clause and parameters, and values to search on or a vector of a SQL where clause and parameters,
perform a delete on the table." perform a delete on the table."
([connectable table where-params] ([connectable table where-params]
(rs/execute! connectable (sql/for-delete table where-params {}) {})) (delete! connectable table where-params {}))
([connectable table where-params opts] ([connectable table where-params opts]
(rs/execute! connectable (sql/for-delete table where-params opts) opts))) (rs/execute! connectable
(sql/for-delete table where-params opts)
(partial into {})
opts)))

View file

@ -206,9 +206,9 @@
into a vector of processed hash maps (rows). into a vector of processed hash maps (rows).
By default, this will create datafiable rows but :row-fn can override that." By default, this will create datafiable rows but :row-fn can override that."
[connectable sql-params opts] [connectable sql-params f opts]
(into [] (into []
(map (or (:row-fn opts) (datafiable-row connectable opts))) (map f)
(p/-execute connectable sql-params opts))) (p/-execute connectable sql-params opts)))
(defn execute-one! (defn execute-one!
@ -216,12 +216,10 @@
just the first processed hash map (row). just the first processed hash map (row).
By default, this will create a datafiable row but :row-fn can override that." By default, this will create a datafiable row but :row-fn can override that."
[connectable sql-params opts] [connectable sql-params f opts]
(let [row-fn (or (:row-fn opts) (datafiable-row connectable opts))] (reduce (fn [_ row] (reduced (f row)))
(reduce (fn [_ row]
(reduced (row-fn row)))
nil nil
(p/-execute connectable sql-params opts)))) (p/-execute connectable sql-params opts)))
(defn- default-schema (defn- default-schema
"The default schema lookup rule for column names. "The default schema lookup rule for column names.
@ -269,6 +267,7 @@
(entity-fn (name fk)) (entity-fn (name fk))
" = ?") " = ?")
v] v]
(datafiable-row connectable opts)
opts)) opts))
(catch Exception _ (catch Exception _
;; assume an exception means we just cannot ;; assume an exception means we just cannot

View file

@ -59,7 +59,8 @@
(quick-bench (quick-bench
(execute-one! con (execute-one! con
["select * from fruit where appearance = ?" "red"] ["select * from fruit where appearance = ?" "red"]
{:row-fn :name})) :name
{}))
;; 5.7 micros -- 3.7x ;; 5.7 micros -- 3.7x
(quick-bench (quick-bench
(jdbc/query {:connection con} (jdbc/query {:connection con}
@ -136,12 +137,14 @@
;; test assoc works ;; test assoc works
(execute-one! con (execute-one! con
["select * from fruit where appearance = ?" "red"] ["select * from fruit where appearance = ?" "red"]
{:row-fn #(assoc % :test :value)}) #(assoc % :test :value)
{})
;; test assoc works ;; test assoc works
(execute! con (execute! con
["select * from fruit where appearance = ?" "red"] ["select * from fruit where appearance = ?" "red"]
{:row-fn #(assoc % :test :value)}) #(assoc % :test :value)
{})
(with-transaction [t con {:rollback-only true}] (with-transaction [t con {:rollback-only true}]
(insert! t :fruit {:id 5, :name "Pear", :appearance "green", :cost 49, :grade 47}) (insert! t :fruit {:id 5, :name "Pear", :appearance "green", :cost 49, :grade 47})