This repository has been archived by the owner on May 15, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
api.clj
80 lines (74 loc) · 2.74 KB
/
api.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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
(ns trident.datomic.api
(:require [trident.util :as u]
[trident.datomic.util :as du]
[datomic.api :as d]
[clojure.java.io :refer [reader writer]]
[me.raynes.fs :as fs]
[clojure.string :as str]))
(declare ^:private storage)
(defn storage-path! [path]
(def storage path))
(defn transact
([conn tx-data]
(future
(with-open [wrtr (writer storage :append true)]
@(transact conn tx-data wrtr))))
([conn tx-data wrtr]
(let [tx-data (for [[op & args :as x] tx-data]
(if (map? x)
x
(conj args (u/pred-> op symbol? keyword))))
result (d/transact conn tx-data)]
(future
(let [{:keys [tx-data db-before db-after] :as result} @result
ident-or-eid #(or (:db/ident (d/entity db-before %)) %)
datoms (for [[e a v _ add] tx-data]
[(ident-or-eid e)
(ident-or-eid a)
(if (du/ref? db-after a)
(ident-or-eid v)
v)
add])]
(.write wrtr (prn-str datoms))
result)))))
(defn- deserialize [{:keys [db eids] :as info} line]
(let [datoms (clojure.edn/read-string {:readers {'datom identity}} line)
[tx-datom datoms] ((juxt first rest) datoms)
resolve-eid #(if (keyword? %)
%
(get eids (str %) (str %)))
datoms (for [[e a v add] datoms]
[(if add :db/add :db/retract)
(resolve-eid e)
a
(if (du/ref? db a) (resolve-eid v) v)])
tx (conj datoms {:db/id "datomic.tx"
:db/txInstant (nth tx-datom 2)})]
tx))
(defn- update-info [info result]
(-> info
(update :eids merge (:tempids result))
(assoc :db (:db-after result))))
(defn connect [db-uri {:keys [schema data tx-fn-ns]}]
(d/delete-database db-uri)
(d/create-database db-uri)
(let [conn (d/connect db-uri)
tmp-storage (fs/temp-file "trident-datomic-api")
txes (remove empty? [schema
(some-> tx-fn-ns du/ns-tx-fns)
data])]
(doseq [tx txes]
@(d/transact conn (conj tx {:db/id "datomic.tx"
:db/txInstant #inst "2000-01-01T00:00:00.000-00:00"})))
(with-open [rdr (reader storage)
wrtr (writer tmp-storage)]
(reduce
(fn [info line]
(let [tx (deserialize info line)
result @(transact conn tx wrtr)]
(update-info info result)))
{:db (d/db conn)}
(line-seq rdr)))
(fs/delete storage)
(fs/rename tmp-storage storage)
conn))