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
  • Loading branch information
michaelstaib authored Sep 30, 2024
1 parent 17a0b77 commit 256dd07
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 77 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Reflection;

namespace HotChocolate.Execution.Projections;

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

PropertyNode AddOrGetNode(PropertyInfo property);

void TryAddNode(PropertyNode newNode);
}
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 @@ -90,79 +90,3 @@ 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);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,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 @@ -399,6 +399,39 @@ public async Task Brand_Details_Requires_Brand_Name()
.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
}
}
""");

Snapshot.Create()
.AddSql(queries)
.AddResult(result)
.MatchMarkdownSnapshot();
}

[Fact]
public async Task Brand_Products_TypeName()
{
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"
}
}
}
```

0 comments on commit 256dd07

Please sign in to comment.