-
Notifications
You must be signed in to change notification settings - Fork 0
/
query.clj
96 lines (88 loc) · 2.16 KB
/
query.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
(ns connective.firestore.query
(:require
[connective.firestore.utils :as utils]
[connective.entity :as entity]
[connective.core :as core]
[firestore-clj.core :as f]))
(defmulti compile-clause
(fn [_ [op & xs]] op))
(defmethod compile-clause :=
[{::keys [query]
:as context} [_ attr value]]
(assert
(and (some? attr)
(some? value)))
(assoc context ::query (f/filter= query (name attr) value)))
(defmethod compile-clause :in
[{::keys [query]
:as context} [_ attr value]]
(assert
(and (some? attr)
(some? value)))
(assoc context ::query (f/filter-in query (name attr) value)))
(defn- compile-clauses
[where]
(fn
[a
ctx]
(reduce
compile-clause
ctx
where)))
(defn compile-entities
[kind]
(fn
[a
{::keys [docs]
:as ctx}]
(assert (some? kind))
(let [entities (for [doc-data docs]
(let [base-entity {::entity/kind kind}
entity (utils/assoc-entity-attributes
ctx
base-entity
doc-data)
entity (core/init-entity
a
ctx
entity)]
(entity/assoc-persisted-value entity))) ]
entities)))
(defn compile
[{::keys [find
collection
where
into]}]
(assert
(and (= find ::doc)
(some? collection)
(or (coll? where) (nil? where))))
(let [clause-fn (compile-clauses where)
entity-fn (if (nil? into)
(fn [a ctx & xs] ctx)
(compile-entities into))]
(fn
[a
{::entity/keys [conn]
:as context}]
(->
(clause-fn
a
(merge context {::query (f/coll conn collection)}))
(as-> $
(assoc
$
::docs
(f/pullv (::query $)))
(entity-fn a $))))))
(defn execute
[a
context
qfn]
(qfn a context))
(defn q
[a
context
query]
(let [qfn (compile query)]
(execute a context qfn)))