next-jdbc/src/next/jdbc/middleware.clj

85 lines
3.5 KiB
Clojure
Raw Normal View History

;; copyright (c) 2019 world singles networks llc
(ns next.jdbc.middleware
(:require [next.jdbc.protocols :as p]
[next.jdbc.result-set :as rs]))
(defn post-processing-adapter
"Given a builder function (e.g., `as-lower-maps`), return a new builder
function that post-processes rows and the result set. The options may
contain post-processing functions that are called on each row and on the
the result set. The options map is provided as a second parameter to these
functions, which should include `:next.jdbc/sql-params` (the vector of SQL
and parameters, in case post-processing needs it):
* `:execute-fn` -- called immediately after the SQL operation completes
* `:row!-fn` -- called on each row as it is fully-realized
* `:rs!-fn` -- called on the whole result set once it is fully-realized
The results of these functions are returned as the rows/result set."
[builder-fn]
(fn [rs opts]
(let [id2 (fn [x _] x)
exec-fn (get opts :execute-fn id2)
opts (exec-fn opts {})
mrsb (builder-fn rs opts)
row!-fn (get opts :row!-fn id2)
rs!-fn (get opts :rs!-fn id2)]
(reify
rs/RowBuilder
(->row [this] (rs/->row mrsb))
(column-count [this] (rs/column-count mrsb))
(with-column [this row i] (rs/with-column mrsb row i))
(row! [this row] (row!-fn (rs/row! mrsb row) opts))
rs/ResultSetBuilder
(->rs [this] (rs/->rs mrsb))
(with-row [this mrs row] (rs/with-row mrsb mrs row))
(rs! [this mrs] (rs!-fn (rs/rs! mrsb mrs) opts))))))
(defrecord JdbcMiddleware [db global-opts]
p/Executable
(-execute [this sql-params opts]
(let [opts (merge global-opts opts)
id2 (fn [x _] x)
builder-fn (get opts :builder-fn rs/as-maps)
sql-params-fn (get opts :sql-params-fn id2)
result (sql-params-fn sql-params opts)]
(p/-execute db
(if (map? result)
(or (:next.jdbc/sql-params result) sql-params)
result)
(assoc (if (map? result) result opts)
:builder-fn
(post-processing-adapter builder-fn)))))
(-execute-one [this sql-params opts]
(let [opts (merge global-opts opts)
id2 (fn [x _] x)
builder-fn (get opts :builder-fn rs/as-maps)
sql-params-fn (get opts :sql-params-fn id2)
result (sql-params-fn sql-params opts)]
(p/-execute-one db
(if (map? result)
(or (:next.jdbc/sql-params result) sql-params)
result)
(assoc (if (map? result) result opts)
:builder-fn
(post-processing-adapter builder-fn)))))
(-execute-all [this sql-params opts]
(let [opts (merge global-opts opts)
id2 (fn [x _] x)
builder-fn (get opts :builder-fn rs/as-maps)
sql-params-fn (get opts :sql-params-fn id2)
result (sql-params-fn sql-params opts)]
(p/-execute-all db
(if (map? result)
(or (:next.jdbc/sql-params result) sql-params)
result)
(assoc (if (map? result) result opts)
:builder-fn
(post-processing-adapter builder-fn))))))
(defn wrapper
""
([db] (JdbcMiddleware. db {}))
([db opts] (JdbcMiddleware. db opts)))