@@ -52,14 +52,14 @@ pub(crate) fn build_query<'a>(
52
52
query = query. filter ( filter) ;
53
53
}
54
54
let order = match (
55
- build_order_by ( entity, field) ?,
55
+ build_order_by ( entity, field, schema ) ?,
56
56
build_order_direction ( field) ?,
57
57
) {
58
- ( Some ( ( attr, value_type) ) , OrderDirection :: Ascending ) => {
59
- EntityOrder :: Ascending ( attr, value_type)
58
+ ( Some ( ( attr, value_type, entity_type ) ) , OrderDirection :: Ascending ) => {
59
+ EntityOrder :: Ascending ( attr, value_type, entity_type )
60
60
}
61
- ( Some ( ( attr, value_type) ) , OrderDirection :: Descending ) => {
62
- EntityOrder :: Descending ( attr, value_type)
61
+ ( Some ( ( attr, value_type, entity_type ) ) , OrderDirection :: Descending ) => {
62
+ EntityOrder :: Descending ( attr, value_type, entity_type )
63
63
}
64
64
( None , _) => EntityOrder :: Default ,
65
65
} ;
@@ -274,21 +274,61 @@ fn list_values(value: Value, filter_type: &str) -> Result<Vec<Value>, QueryExecu
274
274
fn build_order_by (
275
275
entity : ObjectOrInterface ,
276
276
field : & a:: Field ,
277
- ) -> Result < Option < ( String , ValueType ) > , QueryExecutionError > {
277
+ schema : & ApiSchema ,
278
+ ) -> Result < Option < ( String , ValueType , Option < EntityType > ) > , QueryExecutionError > {
278
279
match field. argument_value ( "orderBy" ) {
279
- Some ( r:: Value :: Enum ( name) ) => {
280
- let field = sast:: get_field ( entity, name) . ok_or_else ( || {
281
- QueryExecutionError :: EntityFieldError ( entity. name ( ) . to_owned ( ) , name. clone ( ) )
282
- } ) ?;
283
- sast:: get_field_value_type ( & field. field_type )
284
- . map ( |value_type| Some ( ( name. to_owned ( ) , value_type) ) )
285
- . map_err ( |_| {
286
- QueryExecutionError :: OrderByNotSupportedError (
287
- entity. name ( ) . to_owned ( ) ,
288
- name. clone ( ) ,
289
- )
290
- } )
291
- }
280
+ Some ( r:: Value :: Enum ( name) ) => match parse_field_as_order ( name) {
281
+ ( _, None ) => {
282
+ let field = sast:: get_field ( entity, name) . ok_or_else ( || {
283
+ QueryExecutionError :: EntityFieldError ( entity. name ( ) . to_owned ( ) , name. clone ( ) )
284
+ } ) ?;
285
+ sast:: get_field_value_type ( & field. field_type )
286
+ . map ( |value_type| Some ( ( name. to_owned ( ) , value_type, None ) ) )
287
+ . map_err ( |_| {
288
+ QueryExecutionError :: OrderByNotSupportedError (
289
+ entity. name ( ) . to_owned ( ) ,
290
+ name. clone ( ) ,
291
+ )
292
+ } )
293
+ }
294
+ ( field_name, Some ( child_field_name) ) => {
295
+ let parent_field =
296
+ sast:: get_field ( entity, & field_name. to_string ( ) ) . ok_or_else ( || {
297
+ QueryExecutionError :: EntityFieldError (
298
+ entity. name ( ) . to_owned ( ) ,
299
+ field_name. to_string ( ) ,
300
+ )
301
+ } ) ?;
302
+ let child_type_name = resolve_type_name ( & parent_field. field_type ) ;
303
+ let child_entity = schema
304
+ . object_or_interface ( child_type_name. as_str ( ) )
305
+ . ok_or_else ( || QueryExecutionError :: NamedTypeError ( child_type_name. clone ( ) ) ) ?;
306
+
307
+ let child_field = child_entity
308
+ . field ( & child_field_name. to_string ( ) )
309
+ . ok_or_else ( || {
310
+ QueryExecutionError :: EntityFieldError (
311
+ child_type_name. clone ( ) ,
312
+ child_field_name. to_string ( ) ,
313
+ )
314
+ } ) ?;
315
+
316
+ sast:: get_field_value_type ( & child_field. field_type )
317
+ . map ( |value_type| {
318
+ Some ( (
319
+ child_field_name. to_string ( ) ,
320
+ value_type,
321
+ Some ( EntityType :: new ( child_type_name. clone ( ) ) ) ,
322
+ ) )
323
+ } )
324
+ . map_err ( |_| {
325
+ QueryExecutionError :: OrderByNotSupportedError (
326
+ child_type_name. clone ( ) ,
327
+ child_field_name. to_string ( ) ,
328
+ )
329
+ } )
330
+ }
331
+ } ,
292
332
_ => match field. argument_value ( "text" ) {
293
333
Some ( r:: Value :: Object ( filter) ) => build_fulltext_order_by_from_object ( filter) ,
294
334
None => Ok ( None ) ,
@@ -297,14 +337,23 @@ fn build_order_by(
297
337
}
298
338
}
299
339
340
+ /// Kamil: I don't like it... What if we have `_` in the field name? For now I will use double underscore
341
+ fn parse_field_as_order ( field_name : & String ) -> ( & str , Option < & str > ) {
342
+ let mut field_name_parts = field_name. split ( "__" ) ;
343
+ (
344
+ field_name_parts. next ( ) . expect ( "it should never happen" ) ,
345
+ field_name_parts. next ( ) ,
346
+ )
347
+ }
348
+
300
349
fn build_fulltext_order_by_from_object (
301
350
object : & Object ,
302
- ) -> Result < Option < ( String , ValueType ) > , QueryExecutionError > {
351
+ ) -> Result < Option < ( String , ValueType , Option < EntityType > ) > , QueryExecutionError > {
303
352
object. iter ( ) . next ( ) . map_or (
304
353
Err ( QueryExecutionError :: FulltextQueryRequiresFilter ) ,
305
354
|( key, value) | {
306
355
if let r:: Value :: String ( _) = value {
307
- Ok ( Some ( ( key. clone ( ) , ValueType :: String ) ) )
356
+ Ok ( Some ( ( key. clone ( ) , ValueType :: String , None ) ) )
308
357
} else {
309
358
Err ( QueryExecutionError :: FulltextQueryRequiresFilter )
310
359
}
@@ -601,7 +650,7 @@ mod tests {
601
650
)
602
651
. unwrap( )
603
652
. order,
604
- EntityOrder :: Ascending ( "name" . to_string( ) , ValueType :: String )
653
+ EntityOrder :: Ascending ( "name" . to_string( ) , ValueType :: String , None )
605
654
) ;
606
655
607
656
let field = default_field_with ( "orderBy" , r:: Value :: Enum ( "email" . to_string ( ) ) ) ;
@@ -618,7 +667,7 @@ mod tests {
618
667
)
619
668
. unwrap( )
620
669
. order,
621
- EntityOrder :: Ascending ( "email" . to_string( ) , ValueType :: String )
670
+ EntityOrder :: Ascending ( "email" . to_string( ) , ValueType :: String , None )
622
671
) ;
623
672
}
624
673
@@ -680,7 +729,7 @@ mod tests {
680
729
)
681
730
. unwrap( )
682
731
. order,
683
- EntityOrder :: Ascending ( "name" . to_string( ) , ValueType :: String )
732
+ EntityOrder :: Ascending ( "name" . to_string( ) , ValueType :: String , None )
684
733
) ;
685
734
686
735
let field = default_field_with_vec ( vec ! [
@@ -700,7 +749,7 @@ mod tests {
700
749
)
701
750
. unwrap( )
702
751
. order,
703
- EntityOrder :: Descending ( "name" . to_string( ) , ValueType :: String )
752
+ EntityOrder :: Descending ( "name" . to_string( ) , ValueType :: String , None )
704
753
) ;
705
754
706
755
let field = default_field_with_vec ( vec ! [
@@ -723,7 +772,7 @@ mod tests {
723
772
)
724
773
. unwrap( )
725
774
. order,
726
- EntityOrder :: Ascending ( "name" . to_string( ) , ValueType :: String )
775
+ EntityOrder :: Ascending ( "name" . to_string( ) , ValueType :: String , None )
727
776
) ;
728
777
729
778
// No orderBy -> EntityOrder::Default
0 commit comments