-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
identity_query.clj
108 lines (89 loc) · 3.56 KB
/
identity_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
97
98
99
100
101
102
103
104
105
106
107
108
(ns toucan2.tools.identity-query
(:require
[methodical.core :as m]
[pretty.core :as pretty]
[toucan2.connection :as conn]
[toucan2.instance :as instance]
[toucan2.log :as log]
[toucan2.pipeline :as pipeline]
[toucan2.realize :as realize]))
(set! *warn-on-reflection* true)
(defrecord ^:no-doc IdentityQuery [rows]
pretty/PrettyPrintable
(pretty [_this]
(list `identity-query rows))
realize/Realize
(realize [_this]
(realize/realize rows))
clojure.lang.IReduceInit
(reduce [_this rf init]
(log/debugf :execute "reduce IdentityQuery rows")
(reduce rf init rows)))
(defn identity-query
"A queryable that returns `reducible-rows` as-is without compiling anything or running anything against a database.
Good for mocking stuff.
```clj
(def parrot-query
(identity-query [{:id 1, :name \"Parroty\"}
{:id 2, :name \"Green Friend\"}]))
(select/select ::parrot parrot-query)
=>
[(instance ::parrot {:id 1, :name \"Parroty\"})
(instance ::parrot {:id 2, :name \"Green Friend\"})]
```"
[reducible-rows]
(->IdentityQuery reducible-rows))
;; (m/defmethod pipeline/transduce-execute [#_query-type :default #_model :default #_query IdentityQuery]
;; [rf _query-type model {:keys [rows], :as _query}]
;; (log/debugf :execute "transduce IdentityQuery rows %s" rows)
;; (transduce (if model
;; (map (fn [result-row]
;; (instance/instance model result-row)))
;; identity)
;; rf
;; rows))
;; Not sure I understand how you're supposed to get to these points anyway
(m/defmethod pipeline/compile [#_query-type :default #_model :default #_query IdentityQuery]
[_query-type _model query]
query)
(m/defmethod pipeline/build [#_query-type :default #_model :default #_query IdentityQuery]
"This is an around method so we can intercept anything else that might normally be considered a more specific method
when it dispatches off of more-specific values of `query-type`."
[_query-type _model _parsed-args resolved-query]
resolved-query)
(m/defmethod pipeline/transduce-query [#_query-type :default
#_model IdentityQuery
#_resolved-query :default]
"Allow using an identity query as an 'identity model'."
[rf _query-type model _parsed-args _resolved-query]
(transduce identity rf model))
;;;; Identity connection
(deftype ^:no-doc IdentityConnection []
pretty/PrettyPrintable
(pretty [_this]
(list `->IdentityConnection)))
(m/defmethod conn/do-with-connection IdentityConnection
[connectable f]
{:pre [(ifn? f)]}
(f connectable))
(m/defmethod conn/do-with-transaction IdentityConnection
[connectable _options f]
{:pre [(ifn? f)]}
(f connectable))
(m/defmethod pipeline/transduce-execute-with-connection [#_conn IdentityConnection #_query-type :default #_model :default]
[rf _conn _query-type model id-query]
(assert (instance? IdentityQuery id-query))
(binding [conn/*current-connectable* nil]
(transduce
(map (fn [row]
(if (map? row)
(instance/instance model row)
row)))
rf
(:rows id-query))))
(m/defmethod pipeline/transduce-query [#_query-type :default
#_model :default
#_resolved-query IdentityQuery]
[rf query-type model parsed-args resolved-query]
(binding [conn/*current-connectable* (->IdentityConnection)]
(next-method rf query-type model parsed-args resolved-query)))