@@ -5,15 +5,14 @@ use graphql_parser::query as q;
5
5
use graphql_parser:: schema as s;
6
6
use lazy_static:: lazy_static;
7
7
use std:: collections:: { BTreeMap , HashMap , HashSet } ;
8
- use std:: ops:: Deref ;
9
8
use std:: rc:: Rc ;
10
9
use std:: time:: Instant ;
11
10
12
11
use graph:: data:: graphql:: ext:: ObjectTypeExt ;
13
12
use graph:: prelude:: {
14
- BlockNumber , ChildMultiplicity , Entity , EntityCollection , EntityFilter , EntityLink ,
15
- EntityOrder , EntityWindow , Logger , ParentLink , QueryExecutionError , Schema , Store ,
16
- Value as StoreValue , WindowAttribute ,
13
+ BlockNumber , ChildMultiplicity , EntityCollection , EntityFilter , EntityLink , EntityOrder ,
14
+ EntityWindow , Logger , ParentLink , QueryExecutionError , Schema , Store , Value as StoreValue ,
15
+ WindowAttribute ,
17
16
} ;
18
17
19
18
use crate :: execution:: { ExecutionContext , ObjectOrInterface , Resolver } ;
@@ -87,7 +86,7 @@ impl From<Option<q::TypeCondition>> for TypeCondition {
87
86
/// has an entry mapping the response key to the list of nodes.
88
87
#[ derive( Debug , Clone ) ]
89
88
struct Node {
90
- entity : Entity ,
89
+ entity : BTreeMap < String , q :: Value > ,
91
90
/// We are using an `Rc` here for two reasons: it allows us to defer
92
91
/// copying objects until the end, when converting to `q::Value` forces
93
92
/// us to copy any child that is referenced by multiple parents. It also
@@ -97,8 +96,8 @@ struct Node {
97
96
children : BTreeMap < String , Vec < Rc < Node > > > ,
98
97
}
99
98
100
- impl From < Entity > for Node {
101
- fn from ( entity : Entity ) -> Self {
99
+ impl From < BTreeMap < String , q :: Value > > for Node {
100
+ fn from ( entity : BTreeMap < String , q :: Value > ) -> Self {
102
101
Node {
103
102
entity,
104
103
children : BTreeMap :: default ( ) ,
@@ -137,7 +136,7 @@ fn is_root_node(nodes: &Vec<Node>) -> bool {
137
136
138
137
fn make_root_node ( ) -> Vec < Node > {
139
138
vec ! [ Node {
140
- entity: Entity :: new( ) ,
139
+ entity: BTreeMap :: new( ) ,
141
140
children: BTreeMap :: default ( ) ,
142
141
} ]
143
142
}
@@ -148,23 +147,44 @@ fn make_root_node() -> Vec<Node> {
148
147
/// with any field of the entity.
149
148
impl From < Node > for q:: Value {
150
149
fn from ( node : Node ) -> Self {
151
- let mut map: BTreeMap < _ , _ > = node. entity . into ( ) ;
150
+ let mut map = node. entity ;
152
151
for ( key, nodes) in node. children . into_iter ( ) {
153
152
map. insert ( format ! ( "prefetch:{}" , key) , node_list_as_value ( nodes) ) ;
154
153
}
155
154
q:: Value :: Object ( map)
156
155
}
157
156
}
158
157
159
- impl Deref for Node {
160
- type Target = Entity ;
158
+ trait ValueExt {
159
+ fn as_str ( & self ) -> Option < & str > ;
160
+ }
161
161
162
- fn deref ( & self ) -> & Self :: Target {
163
- & self . entity
162
+ impl ValueExt for q:: Value {
163
+ fn as_str ( & self ) -> Option < & str > {
164
+ match self {
165
+ q:: Value :: String ( s) => Some ( s) ,
166
+ _ => None ,
167
+ }
164
168
}
165
169
}
166
170
167
171
impl Node {
172
+ fn id ( & self ) -> Result < String , graph:: prelude:: failure:: Error > {
173
+ match self . get ( "id" ) {
174
+ None => Err ( graph:: prelude:: failure:: format_err!(
175
+ "Entity is missing an `id` attribute"
176
+ ) ) ,
177
+ Some ( q:: Value :: String ( s) ) => Ok ( s. to_owned ( ) ) ,
178
+ _ => Err ( graph:: prelude:: failure:: format_err!(
179
+ "Entity has non-string `id` attribute"
180
+ ) ) ,
181
+ }
182
+ }
183
+
184
+ fn get ( & self , key : & str ) -> Option < & q:: Value > {
185
+ self . entity . get ( key)
186
+ }
187
+
168
188
fn typename ( & self ) -> & str {
169
189
self . get ( "__typename" )
170
190
. expect ( "all entities have a __typename" )
@@ -288,7 +308,7 @@ impl<'a> JoinCond<'a> {
288
308
. filter_map ( |( id, node) | {
289
309
node. get ( * child_field)
290
310
. and_then ( |value| match value {
291
- StoreValue :: List ( values) => {
311
+ q :: Value :: List ( values) => {
292
312
let values: Vec < _ > = values
293
313
. into_iter ( )
294
314
. filter_map ( |value| {
@@ -382,7 +402,7 @@ impl<'a> Join<'a> {
382
402
. get ( "g$parent_id" )
383
403
. expect ( "the query that produces 'child' ensures there is always a g$parent_id" )
384
404
{
385
- StoreValue :: String ( key) => grouped. entry ( key) . or_default ( ) . push ( child. clone ( ) ) ,
405
+ q :: Value :: String ( key) => grouped. entry ( & key) . or_default ( ) . push ( child. clone ( ) ) ,
386
406
_ => unreachable ! ( "the parent_id returned by the query is always a string" ) ,
387
407
}
388
408
}
@@ -871,6 +891,6 @@ fn fetch<S: Store>(
871
891
}
872
892
873
893
store
874
- . find ( query)
894
+ . find_query_values ( query)
875
895
. map ( |entities| entities. into_iter ( ) . map ( |entity| entity. into ( ) ) . collect ( ) )
876
896
}
0 commit comments