-Added support for any combination of paths and values in JSONPath filter expressions

This commit is contained in:
James Newton-King
2016-12-26 14:43:07 +13:00
parent 5456067b11
commit 4099870390
5 changed files with 347 additions and 141 deletions
@@ -723,6 +723,21 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
Assert.IsTrue(JToken.DeepEquals(new JObject(new JProperty("hi", 3)), t[1]));
}
[Test]
public void LesserQuery_ValueFirst()
{
JArray a = new JArray(
new JObject(new JProperty("hi", 1)),
new JObject(new JProperty("hi", 2)),
new JObject(new JProperty("hi", 3)));
IList<JToken> t = a.SelectTokens("[ ?( 1 < @.hi ) ]").ToList();
Assert.IsNotNull(t);
Assert.AreEqual(2, t.Count);
Assert.IsTrue(JToken.DeepEquals(new JObject(new JProperty("hi", 2)), t[0]));
Assert.IsTrue(JToken.DeepEquals(new JObject(new JProperty("hi", 3)), t[1]));
}
#if !(PORTABLE || DNXCORE50 || PORTABLE40 || NET35 || NET20) || NETSTANDARD1_1
[Test]
public void GreaterQueryBigInteger()
@@ -811,6 +826,79 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
Assert.AreEqual(1L, v.Value);
}
[Test]
public void MultiplePaths()
{
JArray a = JArray.Parse(@"[
{
""price"": 199,
""max_price"": 200
},
{
""price"": 200,
""max_price"": 200
},
{
""price"": 201,
""max_price"": 200
}
]");
var results = a.SelectTokens("[?(@.price > @.max_price)]").ToList();
Assert.AreEqual(1, results.Count);
Assert.AreEqual(a[2], results[0]);
}
[Test]
public void Exists_True()
{
JArray a = JArray.Parse(@"[
{
""price"": 199,
""max_price"": 200
},
{
""price"": 200,
""max_price"": 200
},
{
""price"": 201,
""max_price"": 200
}
]");
var results = a.SelectTokens("[?(true)]").ToList();
Assert.AreEqual(3, results.Count);
Assert.AreEqual(a[0], results[0]);
Assert.AreEqual(a[1], results[1]);
Assert.AreEqual(a[2], results[2]);
}
[Test]
public void Exists_Null()
{
JArray a = JArray.Parse(@"[
{
""price"": 199,
""max_price"": 200
},
{
""price"": 200,
""max_price"": 200
},
{
""price"": 201,
""max_price"": 200
}
]");
var results = a.SelectTokens("[?(true)]").ToList();
Assert.AreEqual(3, results.Count);
Assert.AreEqual(a[0], results[0]);
Assert.AreEqual(a[1], results[1]);
Assert.AreEqual(a[2], results[2]);
}
[Test]
public void WildcardWithProperty()
{
@@ -46,6 +46,31 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
[TestFixture]
public class JPathParseTests : TestFixtureBase
{
[Test]
public void BooleanQuery_TwoValues()
{
JPath path = new JPath("[?(1 > 2)]");
Assert.AreEqual(1, path.Filters.Count);
BooleanQueryExpression booleanExpression = (BooleanQueryExpression)((QueryFilter)path.Filters[0]).Expression;
Assert.AreEqual(new JValue(1), booleanExpression.Left);
Assert.AreEqual(new JValue(1), booleanExpression.Right);
Assert.AreEqual(QueryOperator.GreaterThan, booleanExpression.Operator);
}
[Test]
public void BooleanQuery_TwoPaths()
{
JPath path = new JPath("[?(@.price > @.max_price)]");
Assert.AreEqual(1, path.Filters.Count);
BooleanQueryExpression booleanExpression = (BooleanQueryExpression)((QueryFilter)path.Filters[0]).Expression;
List<PathFilter> leftPaths = (List<PathFilter>)booleanExpression.Left;
List<PathFilter> rightPaths = (List<PathFilter>)booleanExpression.Right;
Assert.AreEqual("price", ((FieldFilter)leftPaths[0]).Name);
Assert.AreEqual("max_price", ((FieldFilter)rightPaths[0]).Name);
Assert.AreEqual(QueryOperator.GreaterThan, booleanExpression.Operator);
}
[Test]
public void SingleProperty()
{
@@ -228,8 +253,9 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
Assert.AreEqual("Blah", ((FieldFilter)path.Filters[0]).Name);
BooleanQueryExpression expressions = (BooleanQueryExpression)((QueryFilter)path.Filters[1]).Expression;
Assert.AreEqual(QueryOperator.Exists, expressions.Operator);
Assert.AreEqual(1, expressions.Path.Count);
Assert.AreEqual("name", ((ScanFilter)expressions.Path[0]).Name);
List<PathFilter> paths = (List<PathFilter>)expressions.Left;
Assert.AreEqual(1, paths.Count);
Assert.AreEqual("name", ((ScanFilter)paths[0]).Name);
}
[Test]
@@ -240,7 +266,7 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
Assert.AreEqual("Blah", ((FieldFilter)path.Filters[0]).Name);
BooleanQueryExpression expressions = (BooleanQueryExpression)((QueryFilter)path.Filters[1]).Expression;
Assert.AreEqual(QueryOperator.Equals, expressions.Operator);
Assert.AreEqual("hi", (string)expressions.Value);
Assert.AreEqual("hi", (string)(JToken)expressions.Right);
}
[Test]
@@ -251,7 +277,7 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
Assert.AreEqual("Blah", ((FieldFilter)path.Filters[0]).Name);
BooleanQueryExpression expressions = (BooleanQueryExpression)((QueryFilter)path.Filters[1]).Expression;
Assert.AreEqual(QueryOperator.Equals, expressions.Operator);
Assert.AreEqual("h'i", (string)expressions.Value);
Assert.AreEqual("h'i", (string)(JToken)expressions.Right);
}
[Test]
@@ -262,7 +288,7 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
Assert.AreEqual("Blah", ((FieldFilter)path.Filters[0]).Name);
BooleanQueryExpression expressions = (BooleanQueryExpression)((QueryFilter)path.Filters[1]).Expression;
Assert.AreEqual(QueryOperator.Equals, expressions.Operator);
Assert.AreEqual("h\\i", (string)expressions.Value);
Assert.AreEqual("h\\i", (string)(JToken)expressions.Right);
}
[Test]
@@ -279,7 +305,7 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
Assert.AreEqual("Blah", ((FieldFilter)path.Filters[0]).Name);
BooleanQueryExpression expressions = (BooleanQueryExpression)((QueryFilter)path.Filters[1]).Expression;
Assert.AreEqual(QueryOperator.Equals, expressions.Operator);
Assert.AreEqual(false, (bool)expressions.Value);
Assert.AreEqual(false, (bool)(JToken)expressions.Right);
}
[Test]
@@ -290,7 +316,7 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
Assert.AreEqual("Blah", ((FieldFilter)path.Filters[0]).Name);
BooleanQueryExpression expressions = (BooleanQueryExpression)((QueryFilter)path.Filters[1]).Expression;
Assert.AreEqual(QueryOperator.Equals, expressions.Operator);
Assert.AreEqual(true, (bool)expressions.Value);
Assert.AreEqual(true, (bool)(JToken)expressions.Right);
}
[Test]
@@ -301,7 +327,7 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
Assert.AreEqual("Blah", ((FieldFilter)path.Filters[0]).Name);
BooleanQueryExpression expressions = (BooleanQueryExpression)((QueryFilter)path.Filters[1]).Expression;
Assert.AreEqual(QueryOperator.Equals, expressions.Operator);
Assert.AreEqual(null, expressions.Value.Value);
Assert.AreEqual(null, ((JValue)expressions.Right).Value);
}
[Test]
@@ -309,7 +335,8 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
{
JPath path = new JPath("[?(@..name<>null)]");
BooleanQueryExpression expressions = (BooleanQueryExpression)((QueryFilter)path.Filters[0]).Expression;
Assert.AreEqual("name", ((ScanFilter)expressions.Path[0]).Name);
List<PathFilter> paths = (List<PathFilter>)expressions.Left;
Assert.AreEqual("name", ((ScanFilter)paths[0]).Name);
}
[Test]
@@ -365,7 +392,7 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
{
JPath path = new JPath("[?(@.name>=12)]");
BooleanQueryExpression expressions = (BooleanQueryExpression)((QueryFilter)path.Filters[0]).Expression;
Assert.AreEqual(12, (int)expressions.Value);
Assert.AreEqual(12, (int)(JToken)expressions.Right);
}
[Test]
@@ -373,7 +400,7 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
{
JPath path = new JPath("[?(@.name>=-12)]");
BooleanQueryExpression expressions = (BooleanQueryExpression)((QueryFilter)path.Filters[0]).Expression;
Assert.AreEqual(-12, (int)expressions.Value);
Assert.AreEqual(-12, (int)(JToken)expressions.Right);
}
[Test]
@@ -381,7 +408,7 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
{
JPath path = new JPath("[?(@.name>=12.1)]");
BooleanQueryExpression expressions = (BooleanQueryExpression)((QueryFilter)path.Filters[0]).Expression;
Assert.AreEqual(12.1d, (double)expressions.Value);
Assert.AreEqual(12.1d, (double)(JToken)expressions.Right);
}
[Test]
@@ -391,10 +418,16 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
CompositeExpression expressions = (CompositeExpression)((QueryFilter)path.Filters[0]).Expression;
Assert.AreEqual(QueryOperator.And, expressions.Operator);
Assert.AreEqual(2, expressions.Expressions.Count);
Assert.AreEqual("name", ((FieldFilter)((BooleanQueryExpression)expressions.Expressions[0]).Path[0]).Name);
Assert.AreEqual(QueryOperator.Exists, expressions.Expressions[0].Operator);
Assert.AreEqual("title", ((FieldFilter)((BooleanQueryExpression)expressions.Expressions[1]).Path[0]).Name);
Assert.AreEqual(QueryOperator.Exists, expressions.Expressions[1].Operator);
var first = (BooleanQueryExpression)expressions.Expressions[0];
var firstPaths = (List<PathFilter>)first.Left;
Assert.AreEqual("name", ((FieldFilter)firstPaths[0]).Name);
Assert.AreEqual(QueryOperator.Exists, first.Operator);
var second = (BooleanQueryExpression)expressions.Expressions[1];
var secondPaths = (List<PathFilter>)second.Left;
Assert.AreEqual("title", ((FieldFilter)secondPaths[0]).Name);
Assert.AreEqual(QueryOperator.Exists, second.Operator);
}
[Test]
@@ -404,15 +437,24 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
CompositeExpression andExpression = (CompositeExpression)((QueryFilter)path.Filters[0]).Expression;
Assert.AreEqual(QueryOperator.And, andExpression.Operator);
Assert.AreEqual(2, andExpression.Expressions.Count);
Assert.AreEqual("name", ((FieldFilter)((BooleanQueryExpression)andExpression.Expressions[0]).Path[0]).Name);
Assert.AreEqual(QueryOperator.Exists, andExpression.Expressions[0].Operator);
var first = (BooleanQueryExpression)andExpression.Expressions[0];
var firstPaths = (List<PathFilter>)first.Left;
Assert.AreEqual("name", ((FieldFilter)firstPaths[0]).Name);
Assert.AreEqual(QueryOperator.Exists, first.Operator);
CompositeExpression orExpression = (CompositeExpression)andExpression.Expressions[1];
Assert.AreEqual(2, orExpression.Expressions.Count);
Assert.AreEqual("title", ((FieldFilter)((BooleanQueryExpression)orExpression.Expressions[0]).Path[0]).Name);
Assert.AreEqual(QueryOperator.Exists, orExpression.Expressions[0].Operator);
Assert.AreEqual("pie", ((FieldFilter)((BooleanQueryExpression)orExpression.Expressions[1]).Path[0]).Name);
Assert.AreEqual(QueryOperator.Exists, orExpression.Expressions[1].Operator);
var orFirst = (BooleanQueryExpression)orExpression.Expressions[0];
var orFirstPaths = (List<PathFilter>)orFirst.Left;
Assert.AreEqual("title", ((FieldFilter)orFirstPaths[0]).Name);
Assert.AreEqual(QueryOperator.Exists, orFirst.Operator);
var orSecond = (BooleanQueryExpression)orExpression.Expressions[1];
var orSecondPaths = (List<PathFilter>)orSecond.Left;
Assert.AreEqual("pie", ((FieldFilter)orSecondPaths[0]).Name);
Assert.AreEqual(QueryOperator.Exists, orSecond.Operator);
}
[Test]
@@ -420,9 +462,10 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
{
JPath path = new JPath("[?($.name>=12.1)]");
BooleanQueryExpression expressions = (BooleanQueryExpression)((QueryFilter)path.Filters[0]).Expression;
Assert.AreEqual(2, expressions.Path.Count);
Assert.IsInstanceOf(typeof(RootFilter), expressions.Path[0]);
Assert.IsInstanceOf(typeof(FieldFilter), expressions.Path[1]);
List<PathFilter> paths = (List<PathFilter>)expressions.Left;
Assert.AreEqual(2, paths.Count);
Assert.IsInstanceOf(typeof(RootFilter), paths[0]);
Assert.IsInstanceOf(typeof(FieldFilter), paths[1]);
}
[Test]
@@ -478,7 +521,7 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
{
JPath path = new JPath("[?(@.name>=5.56789e+0)]");
BooleanQueryExpression expressions = (BooleanQueryExpression)((QueryFilter)path.Filters[0]).Expression;
Assert.AreEqual(5.56789e+0, (double)expressions.Value);
Assert.AreEqual(5.56789e+0, (double)(JToken)expressions.Right);
}
[Test]
@@ -53,7 +53,7 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
new BooleanQueryExpression
{
Operator = QueryOperator.Exists,
Path = new List<PathFilter>
Left = new List<PathFilter>
{
new FieldFilter
{
@@ -64,7 +64,7 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
new BooleanQueryExpression
{
Operator = QueryOperator.Exists,
Path = new List<PathFilter>
Left = new List<PathFilter>
{
new FieldFilter
{
@@ -111,7 +111,7 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
new BooleanQueryExpression
{
Operator = QueryOperator.Exists,
Path = new List<PathFilter>
Left = new List<PathFilter>
{
new FieldFilter
{
@@ -122,7 +122,7 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
new BooleanQueryExpression
{
Operator = QueryOperator.Exists,
Path = new List<PathFilter>
Left = new List<PathFilter>
{
new FieldFilter
{
@@ -164,8 +164,8 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
BooleanQueryExpression e1 = new BooleanQueryExpression
{
Operator = QueryOperator.LessThan,
Value = new JValue(3),
Path = new List<PathFilter>
Right = new JValue(3),
Left = new List<PathFilter>
{
new ArrayIndexFilter()
}
@@ -179,8 +179,8 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
BooleanQueryExpression e2 = new BooleanQueryExpression
{
Operator = QueryOperator.LessThanOrEquals,
Value = new JValue(3),
Path = new List<PathFilter>
Right = new JValue(3),
Left = new List<PathFilter>
{
new ArrayIndexFilter()
}
+90 -55
View File
@@ -423,6 +423,63 @@ namespace Newtonsoft.Json.Linq.JsonPath
};
}
private bool TryParseExpression(out List<PathFilter> expressionPath)
{
if (_expression[_currentIndex] == '$')
{
expressionPath = new List<PathFilter>();
expressionPath.Add(RootFilter.Instance);
}
else if (_expression[_currentIndex] == '@')
{
expressionPath = new List<PathFilter>();
}
else
{
expressionPath = null;
return false;
}
_currentIndex++;
if (ParsePath(expressionPath, _currentIndex, true))
{
throw new JsonException("Path ended with open query.");
}
return true;
}
private JsonException ThrowUnexpectedCharacterException()
{
return new JsonException("Unexpected character while parsing path query: " + _expression[_currentIndex]);
}
private object ParseSide()
{
EatWhitespace();
List<PathFilter> expressionPath;
if (TryParseExpression(out expressionPath))
{
EatWhitespace();
EnsureLength("Path ended with open query.");
return expressionPath;
}
object value;
if (TryParseValue(out value))
{
EatWhitespace();
EnsureLength("Path ended with open query.");
return new JValue(value);
}
throw ThrowUnexpectedCharacterException();
}
private QueryExpression ParseExpression()
{
QueryExpression rootExpression = null;
@@ -430,31 +487,10 @@ namespace Newtonsoft.Json.Linq.JsonPath
while (_currentIndex < _expression.Length)
{
EatWhitespace();
List<PathFilter> expressionPath = new List<PathFilter>();
if (_expression[_currentIndex] == '$')
{
expressionPath.Add(RootFilter.Instance);
}
else if (_expression[_currentIndex] != '@')
{
throw new JsonException("Unexpected character while parsing path query: " + _expression[_currentIndex]);
}
_currentIndex++;
if (ParsePath(expressionPath, _currentIndex, true))
{
throw new JsonException("Path ended with open query.");
}
EatWhitespace();
EnsureLength("Path ended with open query.");
object left = ParseSide();
object right = null;
QueryOperator op;
object value = null;
if (_expression[_currentIndex] == ')'
|| _expression[_currentIndex] == '|'
|| _expression[_currentIndex] == '&')
@@ -465,20 +501,14 @@ namespace Newtonsoft.Json.Linq.JsonPath
{
op = ParseOperator();
EatWhitespace();
EnsureLength("Path ended with open query.");
value = ParseValue();
EatWhitespace();
EnsureLength("Path ended with open query.");
right = ParseSide();
}
BooleanQueryExpression booleanExpression = new BooleanQueryExpression
{
Path = expressionPath,
Left = left,
Operator = op,
Value = (op != QueryOperator.Exists) ? new JValue(value) : null
Right = right
};
if (_expression[_currentIndex] == ')')
@@ -491,8 +521,13 @@ namespace Newtonsoft.Json.Linq.JsonPath
return booleanExpression;
}
if (_expression[_currentIndex] == '&' && Match("&&"))
if (_expression[_currentIndex] == '&')
{
if (!Match("&&"))
{
throw ThrowUnexpectedCharacterException();
}
if (parentExpression == null || parentExpression.Operator != QueryOperator.And)
{
CompositeExpression andExpression = new CompositeExpression { Operator = QueryOperator.And };
@@ -512,8 +547,13 @@ namespace Newtonsoft.Json.Linq.JsonPath
parentExpression.Expressions.Add(booleanExpression);
}
if (_expression[_currentIndex] == '|' && Match("||"))
if (_expression[_currentIndex] == '|')
{
if (!Match("||"))
{
throw ThrowUnexpectedCharacterException();
}
if (parentExpression == null || parentExpression.Operator != QueryOperator.Or)
{
CompositeExpression orExpression = new CompositeExpression { Operator = QueryOperator.Or };
@@ -538,12 +578,13 @@ namespace Newtonsoft.Json.Linq.JsonPath
throw new JsonException("Path ended with open query.");
}
private object ParseValue()
private bool TryParseValue(out object value)
{
char currentChar = _expression[_currentIndex];
if (currentChar == '\'')
{
return ReadQuotedString();
value = ReadQuotedString();
return true;
}
else if (char.IsDigit(currentChar) || currentChar == '-')
{
@@ -561,26 +602,16 @@ namespace Newtonsoft.Json.Linq.JsonPath
if (numberText.IndexOfAny(new char[] { '.', 'E', 'e' }) != -1)
{
double d;
if (double.TryParse(numberText, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out d))
{
return d;
}
else
{
throw new JsonException("Could not read query value.");
}
bool result = double.TryParse(numberText, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out d);
value = d;
return result;
}
else
{
long l;
if (long.TryParse(numberText, NumberStyles.Integer, CultureInfo.InvariantCulture, out l))
{
return l;
}
else
{
throw new JsonException("Could not read query value.");
}
bool result = long.TryParse(numberText, NumberStyles.Integer, CultureInfo.InvariantCulture, out l);
value = l;
return result;
}
}
else
@@ -594,6 +625,7 @@ namespace Newtonsoft.Json.Linq.JsonPath
{
if (Match("true"))
{
value = true;
return true;
}
}
@@ -601,18 +633,21 @@ namespace Newtonsoft.Json.Linq.JsonPath
{
if (Match("false"))
{
return false;
value = false;
return true;
}
}
else if (currentChar == 'n')
{
if (Match("null"))
{
return null;
value = null;
return true;
}
}
throw new JsonException("Could not read query value.");
value = null;
return false;
}
private string ReadQuotedString()
@@ -66,69 +66,45 @@ namespace Newtonsoft.Json.Linq.JsonPath
internal class BooleanQueryExpression : QueryExpression
{
public List<PathFilter> Path { get; set; }
public JValue Value { get; set; }
public object Left { get; set; }
public object Right { get; set; }
private IEnumerable<JToken> GetResult(JToken root, JToken t, object o)
{
JToken resultToken = o as JToken;
if (resultToken != null)
{
return new[] { resultToken };
}
List<PathFilter> pathFilters = o as List<PathFilter>;
if (pathFilters != null)
{
return JPath.Evaluate(pathFilters, root, t, false);
}
return new JToken[0];
}
public override bool IsMatch(JToken root, JToken t)
{
IEnumerable<JToken> pathResult = JPath.Evaluate(Path, root, t, false);
IEnumerable<JToken> rightResults = GetResult(root, t, Right);
IEnumerable<JToken> leftResults = GetResult(root, t, Left);
foreach (JToken r in pathResult)
foreach (JToken leftResult in leftResults)
{
JValue v = r as JValue;
if (v != null)
if (Operator == QueryOperator.Exists)
{
switch (Operator)
{
case QueryOperator.Equals:
if (EqualsWithStringCoercion(v, Value))
{
return true;
}
break;
case QueryOperator.NotEquals:
if (!EqualsWithStringCoercion(v, Value))
{
return true;
}
break;
case QueryOperator.GreaterThan:
if (v.CompareTo(Value) > 0)
{
return true;
}
break;
case QueryOperator.GreaterThanOrEquals:
if (v.CompareTo(Value) >= 0)
{
return true;
}
break;
case QueryOperator.LessThan:
if (v.CompareTo(Value) < 0)
{
return true;
}
break;
case QueryOperator.LessThanOrEquals:
if (v.CompareTo(Value) <= 0)
{
return true;
}
break;
case QueryOperator.Exists:
return true;
}
return true;
}
else
{
switch (Operator)
foreach (JToken rightResult in rightResults)
{
case QueryOperator.Exists:
// you can only specify primative types in a comparison
// notequals will always be true
case QueryOperator.NotEquals:
if (MatchTokens(leftResult, rightResult))
{
return true;
}
}
}
}
@@ -136,6 +112,70 @@ namespace Newtonsoft.Json.Linq.JsonPath
return false;
}
private bool MatchTokens(JToken leftResult, JToken rightResult)
{
JValue leftValue = leftResult as JValue;
JValue rightValue = rightResult as JValue;
if (leftValue != null && rightValue != null)
{
switch (Operator)
{
case QueryOperator.Equals:
if (EqualsWithStringCoercion(leftValue, rightValue))
{
return true;
}
break;
case QueryOperator.NotEquals:
if (!EqualsWithStringCoercion(leftValue, rightValue))
{
return true;
}
break;
case QueryOperator.GreaterThan:
if (leftValue.CompareTo(rightValue) > 0)
{
return true;
}
break;
case QueryOperator.GreaterThanOrEquals:
if (leftValue.CompareTo(rightValue) >= 0)
{
return true;
}
break;
case QueryOperator.LessThan:
if (leftValue.CompareTo(rightValue) < 0)
{
return true;
}
break;
case QueryOperator.LessThanOrEquals:
if (leftValue.CompareTo(rightValue) <= 0)
{
return true;
}
break;
case QueryOperator.Exists:
return true;
}
}
else
{
switch (Operator)
{
case QueryOperator.Exists:
// you can only specify primative types in a comparison
// notequals will always be true
case QueryOperator.NotEquals:
return true;
}
}
return false;
}
private bool EqualsWithStringCoercion(JValue value, JValue queryValue)
{
if (value.Equals(queryValue))