Skip to content

Commit a33fdac

Browse files
committed
chore: migrate parsing logic sparsefields
1 parent 44eb2c4 commit a33fdac

File tree

6 files changed

+80
-94
lines changed

6 files changed

+80
-94
lines changed

src/JsonApiDotNetCore/Internal/Query/QuerySet.cs

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

src/JsonApiDotNetCore/QueryParameters/Common/QueryParameterService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public abstract class QueryParameterService : IQueryParameterService
1616
public virtual string Name { get { return GetParameterNameFromType(); } }
1717

1818
/// <inheritdoc/>
19-
public abstract void Parse(string value);
19+
public abstract void Parse(string key, string value);
2020

2121
/// <summary>
2222
/// Gets the query parameter name from the implementing class name. Trims "Service"

src/JsonApiDotNetCore/QueryParameters/Contracts/IIncludeService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace JsonApiDotNetCore.Query
66
/// <summary>
77
/// Query service to access the inclusion chains.
88
/// </summary>
9-
public interface IIncludeService : IQueryParameterService
9+
public interface IIncludeService
1010
{
1111
/// <summary>
1212
/// Gets the list of included relationships chains for the current request.

src/JsonApiDotNetCore/QueryParameters/IncludeService.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ public class IncludeService : QueryParameterService, IIncludeService
1616
private readonly ICurrentRequest _currentRequest;
1717
private readonly IContextEntityProvider _provider;
1818

19-
public IncludeService(ICurrentRequest currentRequest,
20-
IContextEntityProvider provider)
19+
public IncludeService(ICurrentRequest currentRequest, IContextEntityProvider provider)
2120
{
2221
_currentRequest = currentRequest;
2322
_provider = provider;
@@ -36,7 +35,7 @@ public List<List<RelationshipAttribute>> Get()
3635
}
3736

3837
/// <inheritdoc/>
39-
public override void Parse(string value)
38+
public override void Parse(string _, string value)
4039
{
4140
if (string.IsNullOrWhiteSpace(value))
4241
throw new JsonApiException(400, "Include parameter must not be empty if provided");

src/JsonApiDotNetCore/QueryParameters/SparseFieldsService.cs

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using JsonApiDotNetCore.Internal;
5+
using JsonApiDotNetCore.Internal.Contracts;
6+
using JsonApiDotNetCore.Internal.Query;
7+
using JsonApiDotNetCore.Managers.Contracts;
28
using JsonApiDotNetCore.Models;
39

410
namespace JsonApiDotNetCore.Query
@@ -15,11 +21,15 @@ public class SparseFieldsService : QueryParameterService, ISparseFieldsService
1521
/// The selected field for any included relationships
1622
/// </summary>
1723
private readonly Dictionary<RelationshipAttribute, List<AttrAttribute>> _selectedRelationshipFields;
24+
private readonly ICurrentRequest _currentRequest;
25+
private readonly IContextEntityProvider _provider;
1826

19-
public SparseFieldsService()
27+
public SparseFieldsService(ICurrentRequest currentRequest, IContextEntityProvider provider)
2028
{
2129
_selectedFields = new List<AttrAttribute>();
2230
_selectedRelationshipFields = new Dictionary<RelationshipAttribute, List<AttrAttribute>>();
31+
_currentRequest = currentRequest;
32+
_provider = provider;
2333
}
2434

2535
/// <inheritdoc/>
@@ -33,19 +43,46 @@ public List<AttrAttribute> Get(RelationshipAttribute relationship = null)
3343
}
3444

3545
/// <inheritdoc/>
36-
//public override Parse(AttrAttribute selected, RelationshipAttribute relationship = null)
37-
public override void Parse(string value)
46+
public override void Parse(string key, string value)
3847
{
39-
if (relationship == null)
40-
{
41-
_selectedFields = _selectedFields ?? new List<AttrAttribute>();
42-
_selectedFields.Add(selected);
43-
} else
48+
var primaryResource = _currentRequest.GetRequestResource();
49+
50+
// expected: fields[TYPE]=prop1,prop2
51+
var typeName = key.Split(QueryConstants.OPEN_BRACKET, QueryConstants.CLOSE_BRACKET)[1];
52+
var includedFields = new List<string> { nameof(Identifiable.Id) };
53+
54+
var relationship = primaryResource.Relationships.SingleOrDefault(a => a.Is(typeName));
55+
if (relationship == default && string.Equals(typeName, primaryResource.EntityName, StringComparison.OrdinalIgnoreCase) == false)
56+
return; // includedFields;
57+
58+
var fields = value.Split(QueryConstants.COMMA);
59+
foreach (var field in fields)
4460
{
45-
if (!_selectedRelationshipFields.TryGetValue(relationship, out var fields))
46-
_selectedRelationshipFields.Add(relationship, fields = new List<AttrAttribute>());
61+
if (relationship != default)
62+
{
63+
var relationProperty = _provider.GetContextEntity(relationship.DependentType);
64+
var attr = relationProperty.Attributes.SingleOrDefault(a => a.Is(field));
65+
if (attr == null)
66+
throw new JsonApiException(400, $"'{relationship.DependentType.Name}' does not contain '{field}'.");
67+
68+
if (!_selectedRelationshipFields.TryGetValue(relationship, out var registeredFields))
69+
_selectedRelationshipFields.Add(relationship, registeredFields = new List<AttrAttribute>());
70+
registeredFields.Add(attr);
71+
// e.g. "Owner.Name"
72+
//includedFields.Add(relationship.InternalRelationshipName + "." + attr.InternalAttributeName);
73+
74+
}
75+
else
76+
{
77+
var attr = primaryResource.Attributes.SingleOrDefault(a => a.Is(field));
78+
if (attr == null)
79+
throw new JsonApiException(400, $"'{primaryResource.EntityName}' does not contain '{field}'.");
80+
81+
(_selectedFields = _selectedFields ?? new List<AttrAttribute>()).Add(attr);
4782

48-
fields.Add(selected);
83+
// e.g. "Name"
84+
//includedFields.Add(attr.InternalAttributeName);
85+
}
4986
}
5087
}
5188
}

src/JsonApiDotNetCore/Services/QueryParser.cs

Lines changed: 27 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -22,87 +22,89 @@ public interface IQueryParser
2222

2323
public class QueryParser : IQueryParser
2424
{
25-
private readonly IIncludeService _includeService;
26-
private readonly ISparseFieldsService _fieldQuery;
27-
private readonly IPageQueryService _pageQuery;
25+
private readonly IncludeService _includeService;
26+
private readonly SparseFieldsService _sparseFieldsService;
27+
private readonly FilterService _filterService;
28+
private readonly SortService _sortService;
29+
private readonly OmitDefaultService _omitDefaultService;
30+
private readonly OmitNullService _omitNull;
31+
private readonly PageService _pageService;
32+
2833
private readonly ICurrentRequest _currentRequest;
2934
private readonly IContextEntityProvider _provider;
3035
private readonly IJsonApiOptions _options;
3136
private readonly IServiceProvider _sp;
3237
private ContextEntity _primaryResource;
3338

34-
public QueryParser(IIncludeService includeService,
35-
ISparseFieldsService fieldQuery,
39+
public QueryParser(
3640
ICurrentRequest currentRequest,
3741
IContextEntityProvider provider,
38-
IPageQueryService pageQuery,
3942
IJsonApiOptions options)
4043
{
41-
_includeService = includeService;
42-
_fieldQuery = fieldQuery;
4344
_currentRequest = currentRequest;
44-
_pageQuery = pageQuery;
4545
_provider = provider;
4646
_options = options;
4747
}
4848

49-
public virtual QuerySet Parse(IQueryCollection query)
49+
public virtual void Parse(IQueryCollection query)
5050
{
51-
var type = typeof(IQueryParameterService);
52-
var types = AppDomain.CurrentDomain.GetAssemblies()
53-
.SelectMany(a => a.GetTypes())
54-
.Where(t => t.IsInterface && t.Inherits(type))
55-
.Select(t => (IQueryParameterService)_sp.GetService(t));
56-
5751

5852
_primaryResource = _currentRequest.GetRequestResource();
59-
var querySet = new QuerySet();
6053
var disabledQueries = _currentRequest.DisabledQueryParams;
54+
55+
56+
6157
foreach (var pair in query)
6258
{
6359
if (pair.Key.StartsWith(QueryConstants.FILTER, StringComparison.Ordinal))
6460
{
6561
if (disabledQueries.HasFlag(QueryParams.Filters) == false)
66-
querySet.Filters.AddRange(ParseFilterQuery(pair.Key, pair.Value));
62+
//querySet.Filters.AddRange(ParseFilterQuery(pair.Key, pair.Value));
6763
continue;
6864
}
6965

7066
if (pair.Key.StartsWith(QueryConstants.SORT, StringComparison.Ordinal))
7167
{
7268
if (disabledQueries.HasFlag(QueryParams.Sort) == false)
73-
querySet.SortParameters = ParseSortParameters(pair.Value);
69+
//querySet.SortParameters = ParseSortParameters(pair.Value);
7470
continue;
7571
}
7672

7773
if (pair.Key.StartsWith(_includeService.Name, StringComparison.Ordinal))
7874
{
7975
if (disabledQueries.HasFlag(QueryParams.Include) == false)
80-
_includeService.Parse(pair.Value);
76+
_includeService.Parse(null, pair.Value);
8177
continue;
8278
}
8379

8480
if (pair.Key.StartsWith(QueryConstants.PAGE, StringComparison.Ordinal))
8581
{
8682
if (disabledQueries.HasFlag(QueryParams.Page) == false)
87-
querySet.PageQuery = ParsePageQuery(querySet.PageQuery, pair.Key, pair.Value);
83+
//querySet.PageQuery = ParsePageQuery(querySet.PageQuery, pair.Key, pair.Value);
8884
continue;
8985
}
9086

9187
if (pair.Key.StartsWith(QueryConstants.FIELDS, StringComparison.Ordinal))
9288
{
9389
if (disabledQueries.HasFlag(QueryParams.Fields) == false)
94-
querySet.Fields = ParseFieldsQuery(pair.Key, pair.Value);
90+
_sparseFieldsService.Parse(pair.Key, pair.Value);
9591
continue;
9692
}
9793

9894
if (_options.AllowCustomQueryParameters == false)
9995
throw new JsonApiException(400, $"{pair} is not a valid query.");
10096
}
101-
102-
return querySet;
97+
;
10398
}
10499

105-
100+
private void GetQueryParameterServices()
101+
{
102+
var type = typeof(IQueryParameterService);
103+
var types = AppDomain.CurrentDomain.GetAssemblies()
104+
.SelectMany(a => a.GetTypes())
105+
.Where(t => t.IsInterface && t.Inherits(type))
106+
.Select(t => (IQueryParameterService)_sp.GetService(t));
107+
}
106108

107109
protected virtual List<FilterQuery> ParseFilterQuery(string key, string value)
108110
{
@@ -204,45 +206,6 @@ protected virtual List<SortQuery> ParseSortParameters(string value)
204206
}
205207

206208

207-
protected virtual List<string> ParseFieldsQuery(string key, string value)
208-
{
209-
// expected: fields[TYPE]=prop1,prop2
210-
var typeName = key.Split(QueryConstants.OPEN_BRACKET, QueryConstants.CLOSE_BRACKET)[1];
211-
var includedFields = new List<string> { nameof(Identifiable.Id) };
212-
213-
var relationship = _primaryResource.Relationships.SingleOrDefault(a => a.Is(typeName));
214-
if (relationship == default && string.Equals(typeName, _primaryResource.EntityName, StringComparison.OrdinalIgnoreCase) == false)
215-
return includedFields;
216-
217-
var fields = value.Split(QueryConstants.COMMA);
218-
foreach (var field in fields)
219-
{
220-
if (relationship != default)
221-
{
222-
var relationProperty = _provider.GetContextEntity(relationship.DependentType);
223-
var attr = relationProperty.Attributes.SingleOrDefault(a => a.Is(field));
224-
if (attr == null)
225-
throw new JsonApiException(400, $"'{relationship.DependentType.Name}' does not contain '{field}'.");
226-
227-
_fieldQuery.Register(attr, relationship);
228-
// e.g. "Owner.Name"
229-
includedFields.Add(relationship.InternalRelationshipName + "." + attr.InternalAttributeName);
230-
231-
}
232-
else
233-
{
234-
var attr = _primaryResource.Attributes.SingleOrDefault(a => a.Is(field));
235-
if (attr == null)
236-
throw new JsonApiException(400, $"'{_primaryResource.EntityName}' does not contain '{field}'.");
237-
238-
_fieldQuery.Register(attr, relationship);
239-
// e.g. "Name"
240-
includedFields.Add(attr.InternalAttributeName);
241-
}
242-
}
243-
244-
return includedFields;
245-
}
246209

247210
protected virtual AttrAttribute GetAttribute(string propertyName)
248211
{

0 commit comments

Comments
 (0)