From 72ffb772b4fa6b85836f701618a2571dfd1262ae Mon Sep 17 00:00:00 2001 From: jaredcnance Date: Tue, 28 Mar 2017 21:21:31 -0500 Subject: [PATCH 1/5] chore(csproj): bump package version --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1c886507e1..2ae40744a8 100644 --- a/README.md +++ b/README.md @@ -46,14 +46,14 @@ Install-Package JsonApiDotnetCore - project.json ```json -"JsonApiDotNetCore": "1.2.1" +"JsonApiDotNetCore": "1.3.0" ``` - *.csproj ```xml - + ``` From 8a4c9271898d353d88084f6c06e04a36968abfae Mon Sep 17 00:00:00 2001 From: jaredcnance Date: Tue, 28 Mar 2017 22:21:06 -0500 Subject: [PATCH 2/5] feat(csproj): add System.ValueTuple --- src/JsonApiDotNetCore/JsonApiDotNetCore.csproj | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj b/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj index 8872a457b0..45684b0223 100755 --- a/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj +++ b/src/JsonApiDotNetCore/JsonApiDotNetCore.csproj @@ -1,19 +1,17 @@  - - 1.2.2 + 1.3.0 netcoreapp1.0 JsonApiDotNetCore JsonApiDotNetCore 1.1.1 $(PackageTargetFallback);dnxcore50;portable-net45+win8 - + - - + \ No newline at end of file From 0faabbeb0b567a828e2432ef19249d60d7af8240 Mon Sep 17 00:00:00 2001 From: jaredcnance Date: Tue, 28 Mar 2017 22:22:32 -0500 Subject: [PATCH 3/5] feat(*): add AttrFilterQuery --- .../Extensions/IQueryableExtensions.cs | 2 +- .../Internal/Query/AttrFilterQuery.cs | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 src/JsonApiDotNetCore/Internal/Query/AttrFilterQuery.cs diff --git a/src/JsonApiDotNetCore/Extensions/IQueryableExtensions.cs b/src/JsonApiDotNetCore/Extensions/IQueryableExtensions.cs index abd1686a22..e33359e90d 100644 --- a/src/JsonApiDotNetCore/Extensions/IQueryableExtensions.cs +++ b/src/JsonApiDotNetCore/Extensions/IQueryableExtensions.cs @@ -63,7 +63,7 @@ private static IOrderedQueryable CallGenericOrderMethod(IQuery return (IOrderedQueryable)result; } - public static IQueryable Filter(this IQueryable source, FilterQuery filterQuery) + public static IQueryable Filter(this IQueryable source, AttrFilterQuery filterQuery) { if (filterQuery == null) return source; diff --git a/src/JsonApiDotNetCore/Internal/Query/AttrFilterQuery.cs b/src/JsonApiDotNetCore/Internal/Query/AttrFilterQuery.cs new file mode 100644 index 0000000000..1a691d1d15 --- /dev/null +++ b/src/JsonApiDotNetCore/Internal/Query/AttrFilterQuery.cs @@ -0,0 +1,51 @@ +using System; +using System.Linq; +using JsonApiDotNetCore.Models; +using JsonApiDotNetCore.Services; + +namespace JsonApiDotNetCore.Internal.Query +{ + public class AttrFilterQuery + { + private readonly IJsonApiContext _jsonApiContext; + + public AttrFilterQuery( + IJsonApiContext jsonApiCopntext, + FilterQuery filterQuery) + { + _jsonApiContext = jsonApiCopntext; + + var attribute = GetAttribute(filterQuery.Key); + + if (attribute == null) + throw new JsonApiException("400", $"{filterQuery.Key} is not a valid property."); + + FilteredAttribute = attribute; + PropertyValue = filterQuery.Value; + FilterOperation = GetFilterOperation(filterQuery.Operation); + } + + public AttrAttribute FilteredAttribute { get; set; } + public string PropertyValue { get; set; } + public FilterOperations FilterOperation { get; set; } + + private FilterOperations GetFilterOperation(string prefix) + { + if (prefix.Length == 0) return FilterOperations.eq; + + FilterOperations opertion; + if (!Enum.TryParse(prefix, out opertion)) + throw new JsonApiException("400", $"Invalid filter prefix '{prefix}'"); + + return opertion; + } + + private AttrAttribute GetAttribute(string propertyName) + { + return _jsonApiContext.RequestEntity.Attributes + .FirstOrDefault(attr => + attr.InternalAttributeName.ToLower() == propertyName.ToLower() + ); + } + } +} \ No newline at end of file From c7390ad785e7e51e03e416b584b1b8723f862a7a Mon Sep 17 00:00:00 2001 From: jaredcnance Date: Tue, 28 Mar 2017 22:23:03 -0500 Subject: [PATCH 4/5] refactor(FilterQuery): generalize query using string values --- .../Internal/Query/FilterQuery.cs | 16 ++++----- .../Internal/Query/QuerySet.cs | 33 +++++-------------- 2 files changed, 15 insertions(+), 34 deletions(-) diff --git a/src/JsonApiDotNetCore/Internal/Query/FilterQuery.cs b/src/JsonApiDotNetCore/Internal/Query/FilterQuery.cs index 364d0342c6..11ad90281c 100644 --- a/src/JsonApiDotNetCore/Internal/Query/FilterQuery.cs +++ b/src/JsonApiDotNetCore/Internal/Query/FilterQuery.cs @@ -1,18 +1,16 @@ -using JsonApiDotNetCore.Models; - namespace JsonApiDotNetCore.Internal.Query { public class FilterQuery { - public FilterQuery(AttrAttribute filteredAttribute, string propertyValue, FilterOperations filterOperation) + public FilterQuery(string key, string value, string operation) { - FilteredAttribute = filteredAttribute; - PropertyValue = propertyValue; - FilterOperation = filterOperation; + Key = key; + Value = value; + Operation = operation; } - public AttrAttribute FilteredAttribute { get; set; } - public string PropertyValue { get; set; } - public FilterOperations FilterOperation { get; set; } + public string Key { get; set; } + public string Value { get; set; } + public string Operation { get; set; } } } \ No newline at end of file diff --git a/src/JsonApiDotNetCore/Internal/Query/QuerySet.cs b/src/JsonApiDotNetCore/Internal/Query/QuerySet.cs index 58f1c189f1..80b1870a94 100644 --- a/src/JsonApiDotNetCore/Internal/Query/QuerySet.cs +++ b/src/JsonApiDotNetCore/Internal/Query/QuerySet.cs @@ -74,49 +74,32 @@ private List ParseFilterQuery(string key, string value) var queries = new List(); var propertyName = key.Split('[', ']')[1].ToProperCase(); - var attribute = GetAttribute(propertyName); - - if (attribute == null) - throw new JsonApiException("400", $"{propertyName} is not a valid property."); var values = value.Split(','); foreach(var val in values) - queries.Add(ParseFilterOperation(attribute, val)); + { + (var operation, var filterValue) = ParseFilterOperation(val); + queries.Add(new FilterQuery(propertyName, filterValue, operation)); + } return queries; } - private FilterQuery ParseFilterOperation(AttrAttribute attribute, string value) + private (string operation, string value) ParseFilterOperation(string value) { if(value.Length < 3) - return new FilterQuery(attribute, value, FilterOperations.eq); + return (string.Empty, value); var operation = value.Split(':'); if(operation.Length == 1) - return new FilterQuery(attribute, value, FilterOperations.eq); + return (string.Empty, value); // remove prefix from value var prefix = operation[0]; value = operation[1]; - switch(prefix) - { - case "eq": - return new FilterQuery(attribute, value, FilterOperations.eq); - case "lt": - return new FilterQuery(attribute, value, FilterOperations.lt); - case "gt": - return new FilterQuery(attribute, value, FilterOperations.gt); - case "le": - return new FilterQuery(attribute, value, FilterOperations.le); - case "ge": - return new FilterQuery(attribute, value, FilterOperations.ge); - case "like": - return new FilterQuery(attribute, value, FilterOperations.like); - } - - throw new JsonApiException("400", $"Invalid filter prefix '{prefix}'"); + return (prefix, value);; } private PageQuery ParsePageQuery(string key, string value) From 150aa7c50c344828a7176338ea607d7d1816afbb Mon Sep 17 00:00:00 2001 From: jaredcnance Date: Tue, 28 Mar 2017 22:23:40 -0500 Subject: [PATCH 5/5] feat(default-entity-repository): use the new AttrFilterQuery --- src/JsonApiDotNetCore/Data/DefaultEntityRepository.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/JsonApiDotNetCore/Data/DefaultEntityRepository.cs b/src/JsonApiDotNetCore/Data/DefaultEntityRepository.cs index 62102bec7b..aaff9afb7d 100644 --- a/src/JsonApiDotNetCore/Data/DefaultEntityRepository.cs +++ b/src/JsonApiDotNetCore/Data/DefaultEntityRepository.cs @@ -56,8 +56,10 @@ public virtual IQueryable Filter(IQueryable entities, FilterQ if(filterQuery == null) return entities; + var attributeFilterQuery = new AttrFilterQuery(_jsonApiContext, filterQuery); + return entities - .Filter(filterQuery); + .Filter(attributeFilterQuery); } public virtual IQueryable Sort(IQueryable entities, List sortQueries)