Added negation operator

This commit is contained in:
SuperGouge 2019-01-08 17:20:49 +01:00
parent c818267526
commit 194b1d9fb5
4 changed files with 36 additions and 8 deletions

View File

@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
namespace Sieve.Models
@ -11,6 +12,10 @@ namespace Sieve.Models
private const string EscapedPipePattern = @"(?<!($|[^\\])(\\\\)*?\\)\|";
private static readonly string[] Operators = new string[] {
"!@=*",
"!_=*",
"!@=",
"!_=",
"==*",
"@=*",
"_=*",
@ -34,7 +39,8 @@ namespace Sieve.Models
Values = filterSplits.Length > 1 ? Regex.Split(filterSplits[1], EscapedPipePattern).Select(t => t.Trim()).ToArray() : null;
Operator = Array.Find(Operators, o => value.Contains(o)) ?? "==";
OperatorParsed = GetOperatorParsed(Operator);
OperatorIsCaseInsensitive = Operator.Contains("*");
OperatorIsCaseInsensitive = Operator.EndsWith("*");
OperatorIsNegated = OperatorParsed != FilterOperator.NotEquals && Operator.StartsWith("!");
}
}
@ -47,12 +53,11 @@ namespace Sieve.Models
public string Operator { get; private set; }
private FilterOperator GetOperatorParsed(string Operator)
private FilterOperator GetOperatorParsed(string @operator)
{
switch (Operator.Trim().ToLower())
switch (@operator.TrimEnd('*'))
{
case "==":
case "==*":
return FilterOperator.Equals;
case "!=":
return FilterOperator.NotEquals;
@ -65,10 +70,10 @@ namespace Sieve.Models
case "<=":
return FilterOperator.LessThanOrEqualTo;
case "@=":
case "@=*":
case "!@=":
return FilterOperator.Contains;
case "_=":
case "_=*":
case "!_=":
return FilterOperator.StartsWith;
default:
return FilterOperator.Equals;
@ -77,6 +82,8 @@ namespace Sieve.Models
public bool OperatorIsCaseInsensitive { get; private set; }
public bool OperatorIsNegated { get; private set; }
public bool Equals(FilterTerm other)
{
return Names.SequenceEqual(other.Names)

View File

@ -6,6 +6,7 @@
string[] Names { get; }
string Operator { get; }
bool OperatorIsCaseInsensitive { get; }
bool OperatorIsNegated { get; }
FilterOperator OperatorParsed { get; }
string[] Values { get; }
}

View File

@ -203,13 +203,20 @@ namespace Sieve.Services
.First(m => m.Name == "ToUpper" && m.GetParameters().Length == 0));
}
var expression = GetExpression(filterTerm, filterValue, propertyValue);
if (filterTerm.OperatorIsNegated)
{
expression = Expression.Not(expression);
}
if (innerExpression == null)
{
innerExpression = GetExpression(filterTerm, filterValue, propertyValue);
innerExpression = expression;
}
else
{
innerExpression = Expression.Or(innerExpression, GetExpression(filterTerm, filterValue, propertyValue));
innerExpression = Expression.Or(innerExpression, expression);
}
}
}

View File

@ -101,6 +101,19 @@ namespace SieveUnitTests
Assert.IsTrue(result.Count() == 0);
}
[TestMethod]
public void NotContainsWorks()
{
var model = new SieveModel()
{
Filters = "Title!@=D",
};
var result = _processor.Apply(model, _posts);
Assert.IsTrue(result.Count() == 3);
}
[TestMethod]
public void CanFilterBools()
{