/
firestore_macros.clj
42 lines (40 loc) · 1.51 KB
/
firestore_macros.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
(ns firemore.firestore-macros
(:require
[cljs.core.async :as async]))
(defmacro put-close! [c v]
`(do (async/put! ~c ~v)
(async/close! ~c)))
(defmacro transact-db!
"Reads 'bindings from database, executes body within transaction."
[bindings & body]
(let [transaction (gensym "transaction_")
ret-chan (gensym "return_")
reads (gensym "reads_")]
(loop [[[sym expr :as tuple] & remaining] (reverse (partition 2 bindings))
acc `((fn []
(binding [firemore.firestore/*transaction* ~transaction
firemore.firestore/*transaction-unwritten-docs* ~reads]
(let [result# ~@body]
(doseq [path# (deref ~reads)]
(firemore.firestore/update-db! path# {}))
result#))))]
(if tuple
(recur
remaining
`(let [path# ~expr]
(.then
(.get ~transaction (firemore.firestore/ref path#))
(fn [doc#]
(swap! ~reads conj path#)
(let [~sym (firemore.firestore/doc-upgrader doc#)]
~acc)))))
`(let [~ret-chan (async/chan)
~reads (atom #{})]
(.catch
(.then
(.runTransaction
(.firestore firemore.firestore/FB)
(fn [~transaction] ~acc))
(fn [success#] (put-close! ~ret-chan [success# nil])))
(fn [error#] (put-close! ~ret-chan [nil error#])))
~ret-chan)))))