Skip to content

Commit

Permalink
Fixed issue when required data was present in query. (#7536)
Browse files Browse the repository at this point in the history
(cherry picked from commit 256dd07)
  • Loading branch information
michaelstaib committed Sep 30, 2024
1 parent f74e284 commit c9b50e4
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 77 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#if NET6_0_OR_GREATER
using System.Reflection;

namespace HotChocolate.Execution.Projections;

internal interface IPropertyNodeProvider
{
IReadOnlyList<PropertyNode> Nodes { get; }

PropertyNode AddOrGetNode(PropertyInfo property);

void TryAddNode(PropertyNode newNode);
}
#endif
76 changes: 0 additions & 76 deletions src/HotChocolate/Core/src/Execution/Projections/PropertyNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,80 +91,4 @@ public PropertyNode Clone()
return null;
}
}

internal class PropertyNodeContainer(
List<PropertyNode>? nodes = null)
: IPropertyNodeProvider
{
private static readonly IReadOnlyList<PropertyNode> _emptyNodes = Array.Empty<PropertyNode>();
private List<PropertyNode>? _nodes = nodes;
private bool _sealed;

public IReadOnlyList<PropertyNode> Nodes
=> _nodes ?? _emptyNodes;

public PropertyNode AddOrGetNode(PropertyInfo property)
{
if (_sealed)
{
throw new InvalidOperationException("The property node container is sealed.");
}

_nodes ??= new();

foreach (var node in Nodes)
{
if (node.Property.Name.Equals(property.Name))
{
return node;
}
}

var newNode = new PropertyNode(property);
_nodes.Add(newNode);
return newNode;
}

public void AddNode(PropertyNode newNode)
{
if (_sealed)
{
throw new InvalidOperationException("The property node container is sealed.");
}

_nodes ??= new();

foreach (var node in Nodes)
{
if (node.Property.Name.Equals(node.Property.Name))
{
throw new InvalidOperationException("Duplicate property.");
}
}

_nodes.Add(newNode);
}

public void Seal()
{
if (!_sealed)
{
foreach (var node in Nodes)
{
node.Seal();
}

_sealed = true;
}
}
}

internal interface IPropertyNodeProvider
{
IReadOnlyList<PropertyNode> Nodes { get; }

PropertyNode AddOrGetNode(PropertyInfo property);

void AddNode(PropertyNode newNode);
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#if NET6_0_OR_GREATER
using System.Reflection;

namespace HotChocolate.Execution.Projections;

internal class PropertyNodeContainer(
List<PropertyNode>? nodes = null)
: IPropertyNodeProvider
{
private static readonly IReadOnlyList<PropertyNode> _emptyNodes = Array.Empty<PropertyNode>();
private List<PropertyNode>? _nodes = nodes;
private bool _sealed;

public IReadOnlyList<PropertyNode> Nodes
=> _nodes ?? _emptyNodes;

public PropertyNode AddOrGetNode(PropertyInfo property)
{
if (_sealed)
{
throw new InvalidOperationException("The property node container is sealed.");
}

_nodes ??= new();

foreach (var node in Nodes)
{
if (node.Property.Name.Equals(property.Name))
{
return node;
}
}

var newNode = new PropertyNode(property);
_nodes.Add(newNode);
return newNode;
}

public void TryAddNode(PropertyNode newNode)
{
if (_sealed)
{
throw new InvalidOperationException("The property node container is sealed.");
}

_nodes ??= new();

foreach (var node in _nodes)
{
if (node.Property.Name.Equals(newNode.Property.Name))
{
if (!node.Property.MetadataToken.Equals(newNode.Property.MetadataToken))
{
throw new InvalidOperationException("Duplicate property name.");
}

// we add the child nodes that are not already present
foreach (var newChild in newNode.Nodes)
{
node.TryAddNode(newChild);
}
}
}

_nodes.Add(newNode);
}

public void Seal()
{
if (!_sealed)
{
foreach (var node in Nodes)
{
node.Seal();
}

_sealed = true;
}
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ private void CollectSelections(
{
foreach (var requirement in requirements)
{
parent.AddNode(requirement.Clone());
parent.TryAddNode(requirement.Clone());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,43 @@ public async Task Brand_Details_Requires_Brand_Name()
}
""");

#if NET8_0_OR_GREATER
Snapshot.Create()
#else
Snapshot.Create(postFix: "NET7_0")
#endif
.AddSql(queries)
.AddResult(result)
.MatchMarkdownSnapshot();
}

[Fact]
public async Task Brand_Details_Requires_Brand_Name_2()
{
// Arrange
var queries = new List<string>();
var connectionString = CreateConnectionString();
await CatalogContext.SeedAsync(connectionString);

// Act
var result = await new ServiceCollection()
.AddScoped(_ => queries)
.AddTransient(_ => new CatalogContext(connectionString))
.AddGraphQL()
.AddQueryType<Query>()
.AddTypeExtension<BrandExtensionsWithRequirement>()
.AddPagingArguments()
.ModifyRequestOptions(o => o.IncludeExceptionDetails = true)
.ExecuteRequestAsync(
"""
{
brandById(id: 1) {
name
details
}
}
""");

#if NET8_0_OR_GREATER
Snapshot.Create()
#else
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Brand_Details_Requires_Brand_Name_2

## SQL

```text
-- @__keys_0={ '1' } (DbType = Object)
SELECT b."Name", b."Id"
FROM "Brands" AS b
WHERE b."Id" = ANY (@__keys_0)
```

## Result

```json
{
"data": {
"brandById": {
"name": "Brand0",
"details": "Brand Name:Brand0"
}
}
}
```

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Brand_Details_Requires_Brand_Name_2

## SQL

```text
SELECT b."Name", b."Id"
FROM "Brands" AS b
WHERE b."Id" = 1
```

## Result

```json
{
"data": {
"brandById": {
"name": "Brand0",
"details": "Brand Name:Brand0"
}
}
}
```

0 comments on commit c9b50e4

Please sign in to comment.