1
1
using System . Collections . Concurrent ;
2
+ using System . Collections . Immutable ;
2
3
using HotChocolate . Language ;
3
4
using HotChocolate . Resolvers ;
4
5
using HotChocolate . Types . Descriptors . Definitions ;
@@ -23,7 +24,7 @@ public static ConnectionFlags GetConnectionFlags(IResolverContext context)
23
24
string . Format ( _keyFormat , context . Selection . Id ) ,
24
25
static ( _ , ctx ) =>
25
26
{
26
- if ( ctx . Selection . Field is ObjectField field
27
+ if ( ctx . Selection . Field is ObjectField field
27
28
&& ! field . Flags . HasFlag ( FieldFlags . Connection ) )
28
29
{
29
30
return ConnectionFlags . None ;
@@ -33,48 +34,42 @@ public static ConnectionFlags GetConnectionFlags(IResolverContext context)
33
34
34
35
var connectionFlags = ConnectionFlags . None ;
35
36
36
- if ( ctx . IsSelected ( "edges" ) )
37
+ if ( ctx . IsSelected ( "edges" ) )
37
38
{
38
39
connectionFlags |= ConnectionFlags . Edges ;
39
40
}
40
41
41
- if ( ctx . IsSelected ( "nodes" ) )
42
+ if ( ctx . IsSelected ( "nodes" ) )
42
43
{
43
44
connectionFlags |= ConnectionFlags . Nodes ;
44
45
}
45
46
46
- if ( ctx . IsSelected ( "totalCount" ) )
47
+ if ( ctx . IsSelected ( "totalCount" ) )
47
48
{
48
49
connectionFlags |= ConnectionFlags . TotalCount ;
49
50
}
50
51
51
- if ( ( options . EnableRelativeCursors ?? PagingDefaults . EnableRelativeCursors )
52
- && options . RelativeCursorFields . Count > 0 )
52
+ if ( options . PageInfoFields . Count > 0
53
+ || ( ( options . EnableRelativeCursors ?? PagingDefaults . EnableRelativeCursors )
54
+ && options . RelativeCursorFields . Count > 0 ) )
53
55
{
54
56
var startSelections = ctx . Select ( ) ;
55
57
var selectionContext = new IsSelectedContext ( ctx . Schema , startSelections ) ;
56
58
57
- foreach ( var relativeCursor in options . RelativeCursorFields )
59
+ if ( options . PageInfoFields . Count > 0 )
58
60
{
59
- // we reset the state here so that each visitation starts fresh.
60
- selectionContext . AllSelected = true ;
61
- selectionContext . Selections . Clear ( ) ;
62
- selectionContext . Selections . Push ( startSelections ) ;
63
-
64
- // we parse the selection pattern, we in essence use
65
- // a SelectionSetNode as a selection pattern.
66
- var selectionPattern = ParsePattern ( relativeCursor ) ;
67
-
68
- // then we visit the selection and if one selection of the selection pattern
69
- // is not hit we break the loop and do not set the relative cursor flag.
70
- IsSelectedVisitor . Instance . Visit ( selectionPattern , selectionContext ) ;
71
-
72
- // if however all selections of the selection pattern are
73
- // hit we set the relative cursor flag.
74
- if ( selectionContext . AllSelected )
61
+ if ( ArePatternsMatched ( startSelections , selectionContext , options . PageInfoFields ) )
62
+ {
63
+ connectionFlags |= ConnectionFlags . PageInfo ;
64
+ }
65
+ }
66
+
67
+ if ( ( options . EnableRelativeCursors ?? PagingDefaults . EnableRelativeCursors )
68
+ && options . RelativeCursorFields . Count > 0 )
69
+ {
70
+ if ( ArePatternsMatched ( startSelections , selectionContext , options . RelativeCursorFields ) )
75
71
{
76
72
connectionFlags |= ConnectionFlags . RelativeCursor ;
77
- break ;
78
73
}
79
74
}
80
75
}
@@ -84,6 +79,37 @@ public static ConnectionFlags GetConnectionFlags(IResolverContext context)
84
79
context ) ;
85
80
}
86
81
82
+ private static bool ArePatternsMatched (
83
+ ISelectionCollection startSelections ,
84
+ IsSelectedContext selectionContext ,
85
+ ImmutableHashSet < string > patterns )
86
+ {
87
+ foreach ( var fieldPattern in patterns )
88
+ {
89
+ // we reset the state here so that each visitation starts fresh.
90
+ selectionContext . AllSelected = true ;
91
+ selectionContext . Selections . Clear ( ) ;
92
+ selectionContext . Selections . Push ( startSelections ) ;
93
+
94
+ // we parse the selection pattern, we in essence use
95
+ // a SelectionSetNode as a selection pattern.
96
+ var selectionPattern = ParsePattern ( fieldPattern ) ;
97
+
98
+ // then we visit the selection and if one selection of the selection pattern
99
+ // is not hit we break the loop and signal that the pattern was not hit.
100
+ IsSelectedVisitor . Instance . Visit ( selectionPattern , selectionContext ) ;
101
+
102
+ // if however all selections of the selection pattern are
103
+ // hit we exit early and return true.
104
+ if ( selectionContext . AllSelected )
105
+ {
106
+ return true ;
107
+ }
108
+ }
109
+
110
+ return false ;
111
+ }
112
+
87
113
private static SelectionSetNode ParsePattern ( string selectionSet )
88
114
=> _parsedSelectionSets . GetOrAdd ( selectionSet , static s => ParseSelectionSet ( $ "{{ { s } }}") ) ;
89
115
}
0 commit comments