Skip to content

Commit 430e20f

Browse files
committed
refactor
1 parent d03e5dd commit 430e20f

7 files changed

Lines changed: 66 additions & 198 deletions

File tree

.config/dotnet-tools.json

Lines changed: 0 additions & 13 deletions
This file was deleted.

goatquery-dotnet.sln

Lines changed: 0 additions & 61 deletions
This file was deleted.

src/GoatQuery.AspNetCore/src/Attributes/EnableQueryAttribute.cs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,10 @@ public override void OnActionExecuted(ActionExecutedContext context)
106106
var jsonOptions = context.HttpContext.RequestServices.GetService<
107107
IOptions<JsonOptions>
108108
>();
109-
var namingPolicy = jsonOptions?.Value?.JsonSerializerOptions?.PropertyNamingPolicy;
110-
if (namingPolicy is not null)
111-
{
112-
applyOptions = new QueryOptions()
113-
{
114-
MaxTop = applyOptions.MaxTop,
115-
MaxPropertyMappingDepth = applyOptions.MaxPropertyMappingDepth,
116-
PropertyNamingPolicy = namingPolicy,
117-
};
118-
}
109+
applyOptions.PropertyNamingPolicy = jsonOptions
110+
?.Value
111+
?.JsonSerializerOptions
112+
?.PropertyNamingPolicy;
119113
}
120114

121115
var applyResult = queryable.Apply(query, searchBinder, applyOptions);

src/GoatQuery/src/Ast/OrderByAst.cs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,8 @@ public sealed class OrderByStatement : Node
1111
public OrderByDirection Direction { get; set; }
1212
public List<string> Segments { get; }
1313

14-
public OrderByStatement(Token token)
15-
: base(token)
16-
{
17-
Segments = new List<string> { token.Literal };
18-
}
19-
2014
public OrderByStatement(Token token, OrderByDirection direction)
21-
: base(token)
22-
{
23-
Direction = direction;
24-
Segments = new List<string> { token.Literal };
25-
}
15+
: this(token, new List<string> { token.Literal }, direction) { }
2616

2717
public OrderByStatement(Token token, List<string> segments, OrderByDirection direction)
2818
: base(token)

src/GoatQuery/src/Evaluator/FilterEvaluator.cs

Lines changed: 22 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -106,31 +106,14 @@ private static Result<MemberExpression> BuildPropertyPath(
106106
PropertyMappingTree propertyMappingTree
107107
)
108108
{
109-
var current = startExpression;
110-
var currentMappingTree = propertyMappingTree;
111-
112-
foreach (
113-
var (segment, isLast) in propertyPath.Segments.Select(
114-
(s, i) => (s, i == propertyPath.Segments.Count - 1)
115-
)
116-
)
117-
{
118-
if (!currentMappingTree.TryGetProperty(segment, out var propertyNode))
119-
return Result.Fail($"Invalid property '{segment}' in path");
120-
121-
current = Expression.Property(current, propertyNode.ActualPropertyName);
122-
123-
// Navigate to nested mapping for next segment
124-
if (!isLast)
125-
{
126-
if (!propertyNode.HasNestedMapping)
127-
return Result.Fail($"Property '{segment}' does not support nested navigation");
128-
129-
currentMappingTree = propertyNode.NestedMapping;
130-
}
131-
}
132-
133-
return Result.Ok((MemberExpression)current);
109+
var result = propertyMappingTree.WalkPropertyPath(
110+
propertyPath.Segments,
111+
startExpression,
112+
"path"
113+
);
114+
if (result.IsFailed)
115+
return Result.Fail(result.Errors);
116+
return Result.Ok((MemberExpression)result.Value);
134117
}
135118

136119
private static Result<MemberExpression> ResolvePropertyPathForCollection(
@@ -139,33 +122,14 @@ private static Result<MemberExpression> ResolvePropertyPathForCollection(
139122
PropertyMappingTree propertyMappingTree
140123
)
141124
{
142-
var current = baseExpression;
143-
var currentMappingTree = propertyMappingTree;
144-
145-
for (int i = 0; i < propertyPath.Segments.Count; i++)
146-
{
147-
var segment = propertyPath.Segments[i];
148-
149-
if (!currentMappingTree.TryGetProperty(segment, out var propertyNode))
150-
return Result.Fail(
151-
$"Invalid property '{segment}' in lambda expression property path"
152-
);
153-
154-
current = Expression.Property(current, propertyNode.ActualPropertyName);
155-
156-
// Navigate to nested mapping for next segment
157-
if (i < propertyPath.Segments.Count - 1)
158-
{
159-
if (!propertyNode.HasNestedMapping)
160-
return Result.Fail(
161-
$"Property '{segment}' does not support nested navigation in lambda expression"
162-
);
163-
164-
currentMappingTree = propertyNode.NestedMapping;
165-
}
166-
}
167-
168-
return (MemberExpression)current;
125+
var result = propertyMappingTree.WalkPropertyPath(
126+
propertyPath.Segments,
127+
baseExpression,
128+
"lambda expression property path"
129+
);
130+
if (result.IsFailed)
131+
return Result.Fail(result.Errors);
132+
return Result.Ok((MemberExpression)result.Value);
169133
}
170134

171135
private static bool IsPrimitiveType(Type type)
@@ -390,14 +354,14 @@ bool isEqual
390354
{
391355
var expressionToLower = Expression.Call(expression, StringToLowerMethod);
392356
var valueToLower = Expression.Call(value, StringToLowerMethod);
393-
var nullCheck = Expression.NotEqual(
394-
expression,
395-
Expression.Constant(null, typeof(string))
396-
);
397357

398358
if (isEqual)
399359
{
400360
// eq: (expression != null && expression.ToLower() == value.ToLower())
361+
var nullCheck = Expression.NotEqual(
362+
expression,
363+
Expression.Constant(null, typeof(string))
364+
);
401365
return Expression.AndAlso(
402366
nullCheck,
403367
Expression.Equal(expressionToLower, valueToLower)
@@ -777,29 +741,12 @@ private static Result<Expression> BuildLambdaPropertyPath(
777741
int maxPropertyMappingDepth
778742
)
779743
{
780-
var current = startExpression;
781-
var currentMappingTree = PropertyMappingTreeBuilder.BuildMappingTree(
744+
var mappingTree = PropertyMappingTreeBuilder.BuildMappingTree(
782745
elementType,
783746
maxPropertyMappingDepth
784747
);
785748

786-
foreach (var segment in segments)
787-
{
788-
if (!currentMappingTree.TryGetProperty(segment, out var propertyNode))
789-
{
790-
return Result.Fail($"Invalid property '{segment}' in lambda property path");
791-
}
792-
793-
current = Expression.Property(current, propertyNode.ActualPropertyName);
794-
795-
// Update mapping tree for nested navigation
796-
if (propertyNode.HasNestedMapping)
797-
{
798-
currentMappingTree = propertyNode.NestedMapping;
799-
}
800-
}
801-
802-
return Result.Ok(current);
749+
return mappingTree.WalkPropertyPath(segments, startExpression, "lambda property path");
803750
}
804751

805752
private static Type GetCollectionElementType(Type collectionType)

src/GoatQuery/src/Evaluator/OrderByEvaluator.cs

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -46,34 +46,11 @@ private static Result<Expression> BuildPropertyExpression(
4646
PropertyMappingTree propertyMappingTree
4747
)
4848
{
49-
Expression current = parameterExpression;
50-
var currentMappingTree = propertyMappingTree;
51-
52-
foreach (
53-
var (segment, isLast) in statement.Segments.Select(
54-
(s, i) => (s, i == statement.Segments.Count - 1)
55-
)
56-
)
57-
{
58-
if (!currentMappingTree.TryGetProperty(segment, out var propertyNode))
59-
{
60-
return Result.Fail($"Invalid property '{segment}' within orderby");
61-
}
62-
63-
current = Expression.Property(current, propertyNode.ActualPropertyName);
64-
65-
if (!isLast)
66-
{
67-
if (!propertyNode.HasNestedMapping)
68-
return Result.Fail(
69-
$"Property '{segment}' does not support nested navigation in orderby"
70-
);
71-
72-
currentMappingTree = propertyNode.NestedMapping;
73-
}
74-
}
75-
76-
return Result.Ok(current);
49+
return propertyMappingTree.WalkPropertyPath(
50+
statement.Segments,
51+
parameterExpression,
52+
"orderby"
53+
);
7754
}
7855

7956
private static string GetOrderByMethodName(OrderByDirection direction, bool isAlreadyOrdered)

src/GoatQuery/src/Utilities/PropertyMappingTree.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Linq.Expressions;
45
using System.Reflection;
56
using System.Text.Json;
67
using System.Text.Json.Serialization;
8+
using FluentResults;
79

810
public sealed class PropertyMappingTree
911
{
@@ -34,6 +36,38 @@ internal void AddProperty(string jsonPropertyName, PropertyMappingNode node)
3436
{
3537
((Dictionary<string, PropertyMappingNode>)Properties)[jsonPropertyName] = node;
3638
}
39+
40+
public Result<Expression> WalkPropertyPath(
41+
IReadOnlyList<string> segments,
42+
Expression startExpression,
43+
string errorContext = "path"
44+
)
45+
{
46+
var current = startExpression;
47+
var currentMappingTree = this;
48+
49+
for (int i = 0; i < segments.Count; i++)
50+
{
51+
var segment = segments[i];
52+
53+
if (!currentMappingTree.TryGetProperty(segment, out var propertyNode))
54+
return Result.Fail($"Invalid property '{segment}' in {errorContext}");
55+
56+
current = Expression.Property(current, propertyNode.ActualPropertyName);
57+
58+
if (i < segments.Count - 1)
59+
{
60+
if (!propertyNode.HasNestedMapping)
61+
return Result.Fail(
62+
$"Property '{segment}' does not support nested navigation in {errorContext}"
63+
);
64+
65+
currentMappingTree = propertyNode.NestedMapping;
66+
}
67+
}
68+
69+
return Result.Ok(current);
70+
}
3771
}
3872

3973
public sealed class PropertyMappingNode

0 commit comments

Comments
 (0)