-
Notifications
You must be signed in to change notification settings - Fork 1
/
pull.clj
68 lines (61 loc) · 2.19 KB
/
pull.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
(ns net.eraserhead.clara-eql.pull
(:require
[clara.rules :refer :all]
[clara-eav.eav :as eav]
[edn-query-language.core :as eql]
[net.eraserhead.clara-eql.eav-map :as eav-map])
(:import
(clara_eav.eav EAV)))
(defn- reversed-attribute?
"Returns true if k is a reversed attribute."
[k]
(and (qualified-keyword? k)
(= \_ (get (name k) 0))))
(defn- reverse-attribute
"Reverse an attribute - turns normal into reversed, reversed into normal."
[k]
(if (reversed-attribute? k)
(keyword (namespace k) (subs (name k) 1))
(keyword (namespace k) (str "_" (name k)))))
(defquery eav-map
[]
[?eav-map <- eav-map/eav-map :from [EAV]])
(defquery entity-ref->eid
[:?attribute :?value]
[EAV (= e ?attribute) (= a :db/unique) (= v :db.unique/identity)]
[EAV (= e ?eid) (= a ?attribute) (= v ?value)])
(defn entid [session entity-ref]
(if (coll? entity-ref)
(-> session
(clara.rules/query entity-ref->eid :?attribute (first entity-ref) :?value (second entity-ref))
first
:?eid)
entity-ref))
(defn- pull*
[session eav-map expanded-pattern eid]
(-> (reduce
(fn [result {:keys [key children] :as subpattern}]
(if-some [values (seq (get-in eav-map [eid key]))]
(let [many? (or
(reversed-attribute? key)
(= :db.cardinality/many (first (get-in eav-map [key :db/cardinality]))))
values (cond->> values
true (mapv (fn [value]
(if (fn? value)
(value session)
value)))
children (map #(pull* session eav-map subpattern %)))
value (if many?
(vec values)
(first values))]
(assoc result key value))
result))
{}
(:children expanded-pattern))
not-empty))
(defn pull
[session pattern entity-ref]
(let [eid (entid session entity-ref)
pull-expr (eql/query->ast pattern)
eav-map (:?eav-map (first (clara.rules/query session eav-map)))]
(pull* session eav-map pull-expr eid)))