Skip to content

Commit fe3401c

Browse files
authored
[Fusion] Fixed the composition for pattern based lookups. (#8138)
1 parent 66a8999 commit fe3401c

File tree

1 file changed

+70
-42
lines changed

1 file changed

+70
-42
lines changed

src/HotChocolate/Fusion/src/Composition/Pipeline/Enrichers/PatternEntityEnricher.cs

Lines changed: 70 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -17,60 +17,82 @@ public ValueTask EnrichAsync(
1717
EntityGroup entity,
1818
CancellationToken cancellationToken = default)
1919
{
20+
var completed = new HashSet<(string, string)>();
2021
var regex = CreateRegex();
2122

22-
foreach (var (type, schema) in entity.Parts)
23+
foreach (var entitySchema in entity.Parts.Select(t => t.Schema))
2324
{
24-
if (schema.QueryType is null)
25+
if (entitySchema.QueryType is null)
2526
{
2627
continue;
2728
}
2829

29-
foreach (var entityResolver in schema.QueryType.Fields)
30+
foreach (var entityType in entity.Parts.Select(t => t.Type))
3031
{
31-
var originalTypeName = type.GetOriginalName();
32-
if (entityResolver.Name.AsSpan().StartsWith(originalTypeName, OrdinalIgnoreCase))
32+
var localTypeName = entity.Parts.First(t => t.Schema == entitySchema).Type.GetOriginalName();
33+
34+
foreach (var entityResolver in entitySchema.QueryType.Fields)
3335
{
34-
var splits = regex.Split(entityResolver.Name);
35-
if (splits.Length == 5)
36+
if (completed.Contains((entitySchema.Name, entityResolver.Name)))
3637
{
37-
var typeName = splits[1];
38-
var fieldName = splits[3];
39-
var isList = entityResolver.Type.IsListType();
38+
continue;
39+
}
4040

41-
if (!isList && typeName.Equals(originalTypeName, OrdinalIgnoreCase))
42-
{
43-
var field = type.Fields.FirstOrDefault(f => f.Name.Equals(fieldName, OrdinalIgnoreCase));
44-
if (field is not null)
45-
{
46-
TryRegisterEntityResolver(entity, type, entityResolver, field, schema);
47-
}
48-
}
49-
else if (isList && typeName.Equals(originalTypeName, OrdinalIgnoreCase) ||
50-
(typeName.Length - 1 == originalTypeName.Length &&
51-
typeName.AsSpan()[typeName.Length - 1] == 's'))
41+
42+
if (entityResolver.Name.StartsWith(localTypeName, OrdinalIgnoreCase))
43+
{
44+
var splits = regex.Split(entityResolver.Name);
45+
if (splits.Length == 5)
5246
{
53-
var field = type.Fields.FirstOrDefault(f => f.Name.Equals(fieldName, OrdinalIgnoreCase));
47+
var typeName = splits[1];
48+
var fieldName = splits[3];
49+
var isList = entityResolver.Type.IsListType();
5450

55-
if (field is null)
51+
if (!isList && typeName.Equals(localTypeName, OrdinalIgnoreCase))
5652
{
57-
var fieldPlural = fieldName[..^1];
58-
field = type.Fields.FirstOrDefault(f => f.Name.Equals(fieldPlural, OrdinalIgnoreCase));
53+
var field = entityType.Fields.FirstOrDefault(
54+
f => f.Name.Equals(fieldName, OrdinalIgnoreCase));
55+
if (field is not null &&
56+
TryRegisterEntityResolver(entity, entityType, entityResolver, field, entitySchema))
57+
{
58+
completed.Add((entitySchema.Name, entityResolver.Name));
59+
}
5960
}
60-
61-
if (field is not null)
61+
else if ((isList && typeName.Equals(localTypeName, OrdinalIgnoreCase)) ||
62+
(typeName.Length - 1 == localTypeName.Length &&
63+
typeName.AsSpan()[typeName.Length - 1] == 's'))
6264
{
63-
TryRegisterBatchEntityResolver(entity, type, entityResolver, field, schema);
65+
var field = entityType.Fields.FirstOrDefault(
66+
f => f.Name.Equals(fieldName, OrdinalIgnoreCase));
67+
68+
if (field is null)
69+
{
70+
var fieldPlural = fieldName[..^1];
71+
field = entityType.Fields.FirstOrDefault(
72+
f => f.Name.Equals(fieldPlural, OrdinalIgnoreCase));
73+
}
74+
75+
if (field is not null &&
76+
TryRegisterBatchEntityResolver(
77+
entity,
78+
entityType,
79+
entityResolver,
80+
field,
81+
entitySchema))
82+
{
83+
completed.Add((entitySchema.Name, entityResolver.Name));
84+
}
6485
}
6586
}
6687
}
6788
}
6889
}
6990
}
91+
7092
return default;
7193
}
7294

73-
private static void TryRegisterEntityResolver(
95+
private static bool TryRegisterEntityResolver(
7496
EntityGroup entity,
7597
ObjectTypeDefinition entityType,
7698
OutputFieldDefinition entityResolverField,
@@ -79,12 +101,12 @@ private static void TryRegisterEntityResolver(
79101
{
80102
if (!TryResolveKeyArgument(entityResolverField, keyField, out var keyArg))
81103
{
82-
return;
104+
return false;
83105
}
84106

85-
if (entityResolverField.Type == entityType ||
107+
if (entityResolverField.Type.Equals(entityType, TypeComparison.Structural) ||
86108
(entityResolverField.Type.Kind is TypeKind.NonNull &&
87-
entityResolverField.Type.InnerType() == entityType))
109+
entityResolverField.Type.InnerType().Equals(entityType, TypeComparison.Structural)))
88110
{
89111
var arguments = new List<ArgumentNode>();
90112

@@ -93,12 +115,12 @@ private static void TryRegisterEntityResolver(
93115
null,
94116
new NameNode(entityResolverField.GetOriginalName()),
95117
null,
96-
Array.Empty<DirectiveNode>(),
118+
[],
97119
arguments,
98120
null);
99121

100122
// Create a new SelectionSetNode for the entity resolver
101-
var selectionSet = new SelectionSetNode(new[] { selection, });
123+
var selectionSet = new SelectionSetNode([selection]);
102124

103125
// Create a new EntityResolver for the entity
104126
var resolver = new EntityResolver(
@@ -111,8 +133,8 @@ private static void TryRegisterEntityResolver(
111133
null,
112134
new NameNode(keyField.Name),
113135
null,
114-
Array.Empty<DirectiveNode>(),
115-
Array.Empty<ArgumentNode>(),
136+
[],
137+
[],
116138
null);
117139

118140
var keyFieldDirective = new IsDirective(keyFieldNode);
@@ -122,7 +144,10 @@ private static void TryRegisterEntityResolver(
122144

123145
// Add the new EntityResolver to the entity metadata
124146
entity.Metadata.EntityResolvers.TryAdd(resolver);
147+
return true;
125148
}
149+
150+
return false;
126151
}
127152

128153
private static bool TryResolveKeyArgument(
@@ -167,7 +192,7 @@ private static bool TryResolveKeyArgument(
167192
!keyArgument.ContainsIsDirective();
168193
}
169194

170-
private static void TryRegisterBatchEntityResolver(
195+
private static bool TryRegisterBatchEntityResolver(
171196
EntityGroup entity,
172197
ObjectTypeDefinition entityType,
173198
OutputFieldDefinition entityResolverField,
@@ -176,7 +201,7 @@ private static void TryRegisterBatchEntityResolver(
176201
{
177202
if (!TryResolveBatchKeyArgument(entityResolverField, keyField, out var keyArg))
178203
{
179-
return;
204+
return false;
180205
}
181206

182207
var returnType = entityResolverField.Type;
@@ -186,16 +211,16 @@ private static void TryRegisterBatchEntityResolver(
186211
returnType = returnType.InnerType();
187212
}
188213

189-
if(returnType.Kind != TypeKind.List)
214+
if (returnType.Kind != TypeKind.List)
190215
{
191-
return;
216+
return false;
192217
}
193218

194219
returnType = returnType.InnerType();
195220

196-
if (returnType == entityType ||
221+
if (returnType.Equals(entityType, TypeComparison.Structural) ||
197222
(returnType.Kind is TypeKind.NonNull &&
198-
returnType.InnerType() == entityType))
223+
returnType.InnerType().Equals(entityType, TypeComparison.Structural)))
199224
{
200225
var arguments = new List<ArgumentNode>();
201226

@@ -233,7 +258,10 @@ private static void TryRegisterBatchEntityResolver(
233258

234259
// Add the new EntityResolver to the entity metadata
235260
entity.Metadata.EntityResolvers.TryAdd(resolver);
261+
return true;
236262
}
263+
264+
return false;
237265
}
238266

239267
private static bool TryResolveBatchKeyArgument(

0 commit comments

Comments
 (0)