-
Notifications
You must be signed in to change notification settings - Fork 3
/
api.clj
157 lines (135 loc) · 5.01 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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
(ns datomic-type-extensions.api
(:refer-clojure :exclude [filter sync])
(:require [clojure.walk :refer [postwalk]]
[datomic.api :as d]
[datomic-type-extensions.core :as core]
[datomic-type-extensions.entity :as entity]
[datomic-type-extensions.query :as query]
[datomic-type-extensions.types :as types]
[potemkin :refer [import-vars]]))
;; store attr->attr-info in db
(defn add-backing-types [tx]
(postwalk
(fn [form]
(if-let [type (and (map? form) (:dte/valueType form))]
(assoc form :db/valueType (types/get-backing-datomic-type type))
form))
tx))
(defn query-attr->attr-info [db]
(->> (for [attr (->> (d/q '[:find [?e ...] :where [?e :dte/valueType]] db)
(map #(d/entity db %)))]
[(:db/ident attr) (select-keys attr #{:db/cardinality :dte/valueType})])
(into {})))
(defn find-attr->attr-info [db]
(or (::attr->attr-info db)
(query-attr->attr-info db)))
(def init-txs
[{:db/ident :dte/valueType
:db/valueType :db.type/keyword
:db/cardinality :db.cardinality/one}])
(defn init! [conn]
(when-not (d/entity (d/db conn) :dte/valueType)
@(d/transact conn init-txs)))
(defn prepare-tx-data [db tx-data]
(->> tx-data
(core/serialize-tx-data (find-attr->attr-info db))
(add-backing-types)))
;; datomic.api
(defn transact [connection tx-data]
(d/transact connection (prepare-tx-data (d/db connection) tx-data)))
(defn transact-async [connection tx-data]
(d/transact-async connection (prepare-tx-data (d/db connection) tx-data)))
(defn with [db tx-data]
(d/with db (prepare-tx-data db tx-data)))
(defn entity [db eid]
(let [attr->attr-info (find-attr->attr-info db)]
(entity/wrap (d/entity db (core/serialize-lookup-ref attr->attr-info eid))
attr->attr-info)))
(defn pull [db pattern eid]
(let [attr->attr-info (find-attr->attr-info db)]
(->> (d/pull db pattern (core/serialize-lookup-ref attr->attr-info eid))
(core/deserialize attr->attr-info))))
(defn pull-many [db pattern eids]
(let [attr->attr-info (find-attr->attr-info db)]
(->> (d/pull-many db pattern (map #(core/serialize-lookup-ref attr->attr-info %) eids))
(core/deserialize attr->attr-info))))
(defn since [db t]
(assoc (d/since db t) ::attr->attr-info (find-attr->attr-info db)))
(defn filter [db pred]
(assoc (d/filter db pred) ::attr->attr-info (find-attr->attr-info db)))
(defn history [db]
(assoc (d/history db) ::attr->attr-info (find-attr->attr-info db)))
(defn db [connection]
(let [db (d/db connection)]
(assoc db ::attr->attr-info (find-attr->attr-info db))))
(defn connect [uri]
(let [conn (d/connect uri)]
(init! conn)
conn))
(defn query [query-map]
(let [db (first (:args query-map))
_ (when-not (instance? datomic.db.Db db)
(throw (Exception. "The first input must be a datomic DB so that datomic-type-extensions can deserialize.")))
attr->attr-info (find-attr->attr-info db)]
(query/deserialize-by-pattern
(d/query query-map)
(query/deserialization-pattern (:query query-map) attr->attr-info)
attr->attr-info)))
(defn q [q & inputs]
(query {:query q :args inputs}))
(import-vars [datomic.api
add-listener
as-of
as-of-t
attribute
basis-t
;; connect - implemented to init the :dte/valueType attr
create-database
datoms
;; db - implemented to cache attr->attr-info
delete-database
entid
entid-at
;; entity - wraps datomic.Entity to deserialize attrs when accessed
entity-db
;; filter - implemented to make sure attr->attr-info is preserved
function
gc-storage
get-database-names
;; history - implemented to make sure attr->attr-info is available
ident
index-range
invoke
is-filtered
log
next-t
part
;; pull - implemented to deserialize return value
;; pull-many - implemented to deserialize return value
;; q - implemented to deserialize values
;; query - ditto
release
remove-tx-report-queue
rename-database
request-index
resolve-tempid
seek-datoms
shutdown
;; since - implemented to keep attr->attr-info on the db
since-t
squuid
squuid-time-millis
sync
sync-excise
sync-index
sync-schema
t->tx
tempid
touch
;; transact - implemented to serialize values
;; transact-async - ditto
tx->t
tx-range
tx-report-queue
;; with - implemented to serialize values
])