Better SieveModel, FilterTerm, and SortTerm generics

This commit is contained in:
Biarity 2018-07-02 09:37:40 +10:00
parent 9858c83097
commit 3308f809b1
8 changed files with 102 additions and 37 deletions

View File

@ -5,6 +5,8 @@ namespace Sieve.Models
{ {
public class FilterTerm : IFilterTerm public class FilterTerm : IFilterTerm
{ {
public FilterTerm() { }
private static readonly string[] Operators = new string[] { private static readonly string[] Operators = new string[] {
"==*", "==*",
"@=*", "@=*",
@ -19,23 +21,27 @@ namespace Sieve.Models
"_=" "_="
}; };
public FilterTerm(string filter) public string Filter
{ {
var filterSplits = filter.Split(Operators, StringSplitOptions.RemoveEmptyEntries).Select(t => t.Trim()).ToArray(); set
Names = filterSplits[0].Split('|').Select(t => t.Trim()).ToArray(); {
Value = filterSplits.Length > 1 ? filterSplits[1] : null; var filterSplits = value.Split(Operators, StringSplitOptions.RemoveEmptyEntries).Select(t => t.Trim()).ToArray();
Operator = Array.Find(Operators, o => filter.Contains(o)) ?? "=="; Names = filterSplits[0].Split('|').Select(t => t.Trim()).ToArray();
OperatorParsed = GetOperatorParsed(Operator); Value = filterSplits.Length > 1 ? filterSplits[1] : null;
OperatorIsCaseInsensitive = Operator.Contains("*"); Operator = Array.Find(Operators, o => value.Contains(o)) ?? "==";
OperatorParsed = GetOperatorParsed(Operator);
OperatorIsCaseInsensitive = Operator.Contains("*");
}
} }
public string[] Names { get; } public string[] Names { get; private set; }
public FilterOperator OperatorParsed { get; } public FilterOperator OperatorParsed { get; private set; }
public string Value { get; } public string Value { get; private set; }
public string Operator { get; } public string Operator { get; private set; }
private FilterOperator GetOperatorParsed(string Operator) private FilterOperator GetOperatorParsed(string Operator)
{ {
@ -65,6 +71,6 @@ namespace Sieve.Models
} }
} }
public bool OperatorIsCaseInsensitive { get; } public bool OperatorIsCaseInsensitive { get; private set; }
} }
} }

View File

@ -2,6 +2,7 @@
{ {
public interface IFilterTerm public interface IFilterTerm
{ {
string Filter { set; }
string[] Names { get; } string[] Names { get; }
string Operator { get; } string Operator { get; }
bool OperatorIsCaseInsensitive { get; } bool OperatorIsCaseInsensitive { get; }

View File

@ -1,8 +1,14 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
namespace Sieve.Models namespace Sieve.Models
{ {
public interface ISieveModel<TFilterTerm, TSortTerm> public interface ISieveModel : ISieveModel<IFilterTerm, ISortTerm>
{
}
public interface ISieveModel<TFilterTerm, TSortTerm>
where TFilterTerm : IFilterTerm where TFilterTerm : IFilterTerm
where TSortTerm : ISortTerm where TSortTerm : ISortTerm
{ {

View File

@ -2,6 +2,7 @@
{ {
public interface ISortTerm public interface ISortTerm
{ {
string Sort { set; }
bool Descending { get; } bool Descending { get; }
string Name { get; } string Name { get; }
} }

View File

@ -1,11 +1,16 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization; using System.Runtime.Serialization;
namespace Sieve.Models namespace Sieve.Models
{ {
public class SieveModel : SieveModel<FilterTerm, SortTerm> { }
[DataContract] [DataContract]
public class SieveModel : ISieveModel<IFilterTerm, ISortTerm> public class SieveModel<TFilterTerm, TSortTerm> : ISieveModel<TFilterTerm, TSortTerm>
where TFilterTerm : IFilterTerm, new()
where TSortTerm : ISortTerm, new()
{ {
[DataMember] [DataMember]
public string Filters { get; set; } public string Filters { get; set; }
@ -19,24 +24,32 @@ namespace Sieve.Models
[DataMember, Range(1, int.MaxValue)] [DataMember, Range(1, int.MaxValue)]
public int? PageSize { get; set; } public int? PageSize { get; set; }
public List<IFilterTerm> FiltersParsed public List<TFilterTerm> FiltersParsed
{ {
get get
{ {
if (Filters != null) if (Filters != null)
{ {
var value = new List<IFilterTerm>(); var value = new List<TFilterTerm>();
foreach (var filter in Filters.Split(',')) foreach (var filter in Filters.Split(','))
{ {
if (filter.StartsWith("(")) if (filter.StartsWith("("))
{ {
var filterOpAndVal = filter.Substring(filter.LastIndexOf(")") + 1); var filterOpAndVal = filter.Substring(filter.LastIndexOf(")") + 1);
var subfilters = filter.Replace(filterOpAndVal, "").Replace("(", "").Replace(")", ""); var subfilters = filter.Replace(filterOpAndVal, "").Replace("(", "").Replace(")", "");
value.Add(new FilterTerm(subfilters + filterOpAndVal)); var filterTerm = new TFilterTerm
{
Filter = subfilters + filterOpAndVal
};
value.Add(filterTerm);
} }
else else
{ {
value.Add(new FilterTerm(filter)); var filterTerm = new TFilterTerm
{
Filter = filter
};
value.Add(filterTerm);
} }
} }
return value; return value;
@ -48,16 +61,20 @@ namespace Sieve.Models
} }
} }
public List<ISortTerm> SortsParsed public List<TSortTerm> SortsParsed
{ {
get get
{ {
if (Sorts != null) if (Sorts != null)
{ {
var value = new List<ISortTerm>(); var value = new List<TSortTerm>();
foreach (var sort in Sorts.Split(',')) foreach (var sort in Sorts.Split(','))
{ {
value.Add(new SortTerm(sort)); var sortTerm = new TSortTerm()
{
Sort = sort
};
value.Add(sortTerm);
} }
return value; return value;
} }
@ -65,6 +82,7 @@ namespace Sieve.Models
{ {
return null; return null;
} }
} }
} }
} }

View File

@ -2,11 +2,16 @@
{ {
public class SortTerm : ISortTerm public class SortTerm : ISortTerm
{ {
private readonly string _sort; public SortTerm() { }
public SortTerm(string sort) private string _sort;
public string Sort
{ {
_sort = sort; set
{
_sort = value;
}
} }
public string Name => (_sort.StartsWith("-")) ? _sort.Substring(1) : _sort; public string Name => (_sort.StartsWith("-")) ? _sort.Substring(1) : _sort;

View File

@ -3,15 +3,22 @@ using Sieve.Models;
namespace Sieve.Services namespace Sieve.Services
{ {
public interface ISieveProcessor : ISieveProcessor<ISieveModel<IFilterTerm, ISortTerm>, IFilterTerm, ISortTerm> public interface ISieveProcessor : ISieveProcessor<SieveModel, FilterTerm, SortTerm>
{
}
public interface ISieveProcessor<TFilterTerm, TSortTerm> : ISieveProcessor<SieveModel<TFilterTerm, TSortTerm>, TFilterTerm, TSortTerm>
where TFilterTerm : IFilterTerm, new()
where TSortTerm : ISortTerm, new()
{ {
} }
public interface ISieveProcessor<TSieveModel, TFilterTerm, TSortTerm> public interface ISieveProcessor<TSieveModel, TFilterTerm, TSortTerm>
where TSieveModel : class, ISieveModel<TFilterTerm, TSortTerm> where TSieveModel : class, ISieveModel<TFilterTerm, TSortTerm>
where TFilterTerm : IFilterTerm where TFilterTerm : IFilterTerm, new()
where TSortTerm : ISortTerm where TSortTerm : ISortTerm, new()
{ {
IQueryable<TEntity> Apply<TEntity>( IQueryable<TEntity> Apply<TEntity>(

View File

@ -11,7 +11,28 @@ using Sieve.Models;
namespace Sieve.Services namespace Sieve.Services
{ {
public class SieveProcessor : SieveProcessor<ISieveModel<IFilterTerm, ISortTerm>, IFilterTerm, ISortTerm>, ISieveProcessor public class SieveProcessor : SieveProcessor<SieveModel, FilterTerm, SortTerm>, ISieveProcessor
{
public SieveProcessor(IOptions<SieveOptions> options) : base(options)
{
}
public SieveProcessor(IOptions<SieveOptions> options, ISieveCustomSortMethods customSortMethods) : base(options, customSortMethods)
{
}
public SieveProcessor(IOptions<SieveOptions> options, ISieveCustomFilterMethods customFilterMethods) : base(options, customFilterMethods)
{
}
public SieveProcessor(IOptions<SieveOptions> options, ISieveCustomSortMethods customSortMethods, ISieveCustomFilterMethods customFilterMethods) : base(options, customSortMethods, customFilterMethods)
{
}
}
public class SieveProcessor<TFilterTerm, TSortTerm> : SieveProcessor<SieveModel<TFilterTerm, TSortTerm>, TFilterTerm, TSortTerm>, ISieveProcessor<TFilterTerm, TSortTerm>
where TFilterTerm : IFilterTerm, new()
where TSortTerm : ISortTerm, new()
{ {
public SieveProcessor(IOptions<SieveOptions> options) : base(options) public SieveProcessor(IOptions<SieveOptions> options) : base(options)
{ {
@ -32,8 +53,8 @@ namespace Sieve.Services
public class SieveProcessor<TSieveModel, TFilterTerm, TSortTerm> : ISieveProcessor<TSieveModel, TFilterTerm, TSortTerm> public class SieveProcessor<TSieveModel, TFilterTerm, TSortTerm> : ISieveProcessor<TSieveModel, TFilterTerm, TSortTerm>
where TSieveModel : class, ISieveModel<TFilterTerm, TSortTerm> where TSieveModel : class, ISieveModel<TFilterTerm, TSortTerm>
where TFilterTerm : IFilterTerm where TFilterTerm : IFilterTerm, new()
where TSortTerm : ISortTerm where TSortTerm : ISortTerm, new()
{ {
private readonly IOptions<SieveOptions> _options; private readonly IOptions<SieveOptions> _options;
private readonly ISieveCustomSortMethods _customSortMethods; private readonly ISieveCustomSortMethods _customSortMethods;