|
| 1 | +(ns clj-postgres-async.impl.impl |
| 2 | + (:require [clojure.string :as string] |
| 3 | + [clojure.core.async :refer [chan put! go <!]]) |
| 4 | + (:import [java.util.function Consumer])) |
| 5 | + |
| 6 | +(defmacro defasync [name args] |
| 7 | + `(defn ~name [~@args] |
| 8 | + (let [c# (chan 1)] |
| 9 | + (~(symbol (subs (str name) 1)) ~@args #(put! c# [%1 %2])) |
| 10 | + c#))) |
| 11 | + |
| 12 | +(defmacro consumer-fn [[param] body] |
| 13 | + `(reify Consumer (accept [_# ~param] |
| 14 | + (~@body)))) |
| 15 | + |
| 16 | +(defn result->map [result columns] |
| 17 | + (letfn [(row->map [row rowmap col] |
| 18 | + (assoc rowmap (keyword (.toLowerCase col)) (.get row col)))] |
| 19 | + {:updated (.updatedRows result) |
| 20 | + :rows (into [] (map (fn [row] |
| 21 | + (reduce (partial row->map row) {} columns)) |
| 22 | + result))})) |
| 23 | + |
| 24 | +(defn list-columns [data] |
| 25 | + (for [e data] (-> e (first) (name)))) |
| 26 | + |
| 27 | +(defn list-params [start end] |
| 28 | + (for [i (range start end)] (str "$" i))) |
| 29 | + |
| 30 | +(defn create-insert-sql [{:keys [table returning]} data] |
| 31 | + (str "INSERT INTO " table " (" |
| 32 | + (string/join ", " (list-columns data)) |
| 33 | + ") VALUES (" |
| 34 | + (string/join ", " (list-params 1 (inc (count data)))) ")" |
| 35 | + (when returning |
| 36 | + (str " RETURNING " returning)))) |
| 37 | + |
| 38 | +(defn create-update-sql [{:keys [table returning where]} data] |
| 39 | + (str "UPDATE " table |
| 40 | + " SET (" |
| 41 | + (string/join "," (list-columns data)) |
| 42 | + ")=(" |
| 43 | + (string/join "," (list-params (count where) (+ (count where) (count data)))) |
| 44 | + ") WHERE " (first where) |
| 45 | + (when returning |
| 46 | + (str " RETURNING " returning)))) |
| 47 | + |
| 48 | +(defn async-sql-bindings [bindings err] |
| 49 | + "Converts bindings x (f) to [x err] (if [err] [nil err] (<! (f)))" |
| 50 | + (let [vars (map (fn [v] |
| 51 | + [v err]) |
| 52 | + (take-nth 2 bindings)) |
| 53 | + fs (map (fn [f] |
| 54 | + `(if ~err [nil ~err] (<! ~f))) |
| 55 | + (take-nth 2 (rest bindings)))] |
| 56 | + (list* [err err] [nil nil] (interleave vars fs)))) |
| 57 | + |
| 58 | + |
| 59 | + |
| 60 | + |
0 commit comments