Skip to content

Commit f196dae

Browse files
authored
Merge pull request #79 from Research-Institute/feat/#77
Extensible Filtering
2 parents 8a14139 + 150aa7c commit f196dae

File tree

7 files changed

+75
-43
lines changed

7 files changed

+75
-43
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,14 @@ Install-Package JsonApiDotnetCore
4646

4747
- project.json
4848
```json
49-
"JsonApiDotNetCore": "1.2.1"
49+
"JsonApiDotNetCore": "1.3.0"
5050
```
5151

5252
- *.csproj
5353
```xml
5454
<ItemGroup>
5555
<!-- ... -->
56-
<PackageReference Include="JsonApiDotNetCore" Version="1.2.1" />
56+
<PackageReference Include="JsonApiDotNetCore" Version="1.3.0" />
5757
</ItemGroup>
5858
```
5959

src/JsonApiDotNetCore/Data/DefaultEntityRepository.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ public virtual IQueryable<TEntity> Filter(IQueryable<TEntity> entities, FilterQ
5656
if(filterQuery == null)
5757
return entities;
5858

59+
var attributeFilterQuery = new AttrFilterQuery(_jsonApiContext, filterQuery);
60+
5961
return entities
60-
.Filter(filterQuery);
62+
.Filter(attributeFilterQuery);
6163
}
6264

6365
public virtual IQueryable<TEntity> Sort(IQueryable<TEntity> entities, List<SortQuery> sortQueries)

src/JsonApiDotNetCore/Extensions/IQueryableExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ private static IOrderedQueryable<TSource> CallGenericOrderMethod<TSource>(IQuery
6363
return (IOrderedQueryable<TSource>)result;
6464
}
6565

66-
public static IQueryable<TSource> Filter<TSource>(this IQueryable<TSource> source, FilterQuery filterQuery)
66+
public static IQueryable<TSource> Filter<TSource>(this IQueryable<TSource> source, AttrFilterQuery filterQuery)
6767
{
6868
if (filterQuery == null)
6969
return source;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System;
2+
using System.Linq;
3+
using JsonApiDotNetCore.Models;
4+
using JsonApiDotNetCore.Services;
5+
6+
namespace JsonApiDotNetCore.Internal.Query
7+
{
8+
public class AttrFilterQuery
9+
{
10+
private readonly IJsonApiContext _jsonApiContext;
11+
12+
public AttrFilterQuery(
13+
IJsonApiContext jsonApiCopntext,
14+
FilterQuery filterQuery)
15+
{
16+
_jsonApiContext = jsonApiCopntext;
17+
18+
var attribute = GetAttribute(filterQuery.Key);
19+
20+
if (attribute == null)
21+
throw new JsonApiException("400", $"{filterQuery.Key} is not a valid property.");
22+
23+
FilteredAttribute = attribute;
24+
PropertyValue = filterQuery.Value;
25+
FilterOperation = GetFilterOperation(filterQuery.Operation);
26+
}
27+
28+
public AttrAttribute FilteredAttribute { get; set; }
29+
public string PropertyValue { get; set; }
30+
public FilterOperations FilterOperation { get; set; }
31+
32+
private FilterOperations GetFilterOperation(string prefix)
33+
{
34+
if (prefix.Length == 0) return FilterOperations.eq;
35+
36+
FilterOperations opertion;
37+
if (!Enum.TryParse<FilterOperations>(prefix, out opertion))
38+
throw new JsonApiException("400", $"Invalid filter prefix '{prefix}'");
39+
40+
return opertion;
41+
}
42+
43+
private AttrAttribute GetAttribute(string propertyName)
44+
{
45+
return _jsonApiContext.RequestEntity.Attributes
46+
.FirstOrDefault(attr =>
47+
attr.InternalAttributeName.ToLower() == propertyName.ToLower()
48+
);
49+
}
50+
}
51+
}
Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
using JsonApiDotNetCore.Models;
2-
31
namespace JsonApiDotNetCore.Internal.Query
42
{
53
public class FilterQuery
64
{
7-
public FilterQuery(AttrAttribute filteredAttribute, string propertyValue, FilterOperations filterOperation)
5+
public FilterQuery(string key, string value, string operation)
86
{
9-
FilteredAttribute = filteredAttribute;
10-
PropertyValue = propertyValue;
11-
FilterOperation = filterOperation;
7+
Key = key;
8+
Value = value;
9+
Operation = operation;
1210
}
1311

14-
public AttrAttribute FilteredAttribute { get; set; }
15-
public string PropertyValue { get; set; }
16-
public FilterOperations FilterOperation { get; set; }
12+
public string Key { get; set; }
13+
public string Value { get; set; }
14+
public string Operation { get; set; }
1715
}
1816
}

src/JsonApiDotNetCore/Internal/Query/QuerySet.cs

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -74,49 +74,32 @@ private List<FilterQuery> ParseFilterQuery(string key, string value)
7474
var queries = new List<FilterQuery>();
7575

7676
var propertyName = key.Split('[', ']')[1].ToProperCase();
77-
var attribute = GetAttribute(propertyName);
78-
79-
if (attribute == null)
80-
throw new JsonApiException("400", $"{propertyName} is not a valid property.");
8177

8278
var values = value.Split(',');
8379
foreach(var val in values)
84-
queries.Add(ParseFilterOperation(attribute, val));
80+
{
81+
(var operation, var filterValue) = ParseFilterOperation(val);
82+
queries.Add(new FilterQuery(propertyName, filterValue, operation));
83+
}
8584

8685
return queries;
8786
}
8887

89-
private FilterQuery ParseFilterOperation(AttrAttribute attribute, string value)
88+
private (string operation, string value) ParseFilterOperation(string value)
9089
{
9190
if(value.Length < 3)
92-
return new FilterQuery(attribute, value, FilterOperations.eq);
91+
return (string.Empty, value);
9392

9493
var operation = value.Split(':');
9594

9695
if(operation.Length == 1)
97-
return new FilterQuery(attribute, value, FilterOperations.eq);
96+
return (string.Empty, value);
9897

9998
// remove prefix from value
10099
var prefix = operation[0];
101100
value = operation[1];
102101

103-
switch(prefix)
104-
{
105-
case "eq":
106-
return new FilterQuery(attribute, value, FilterOperations.eq);
107-
case "lt":
108-
return new FilterQuery(attribute, value, FilterOperations.lt);
109-
case "gt":
110-
return new FilterQuery(attribute, value, FilterOperations.gt);
111-
case "le":
112-
return new FilterQuery(attribute, value, FilterOperations.le);
113-
case "ge":
114-
return new FilterQuery(attribute, value, FilterOperations.ge);
115-
case "like":
116-
return new FilterQuery(attribute, value, FilterOperations.like);
117-
}
118-
119-
throw new JsonApiException("400", $"Invalid filter prefix '{prefix}'");
102+
return (prefix, value);;
120103
}
121104

122105
private PageQuery ParsePageQuery(string key, string value)
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
<Project Sdk="Microsoft.NET.Sdk">
2-
32
<PropertyGroup>
4-
<VersionPrefix>1.2.2</VersionPrefix>
3+
<VersionPrefix>1.3.0</VersionPrefix>
54
<TargetFramework>netcoreapp1.0</TargetFramework>
65
<AssemblyName>JsonApiDotNetCore</AssemblyName>
76
<PackageId>JsonApiDotNetCore</PackageId>
87
<RuntimeFrameworkVersion>1.1.1</RuntimeFrameworkVersion>
98
<PackageTargetFallback>$(PackageTargetFallback);dnxcore50;portable-net45+win8</PackageTargetFallback>
109
</PropertyGroup>
11-
1210
<ItemGroup>
1311
<PackageReference Include="Microsoft.AspNetCore.Routing" Version="1.1.1" />
1412
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
1513
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="1.1.1" />
1614
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.1" />
15+
<PackageReference Include="System.ValueTuple" Version="4.3.0" />
1716
</ItemGroup>
18-
19-
</Project>
17+
</Project>

0 commit comments

Comments
 (0)