mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 16:50:58 +00:00
Improved predicate parsing.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@25235 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
fb6739feb4
commit
eab08f939e
2 changed files with 80 additions and 17 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2007-06-11 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
|
* Source/NSPredicate.m: Improved predicate parsing. Handle more
|
||||||
|
alternate key strings, implemented BETWEEN, use compare:options:
|
||||||
|
for string equality test and handle in for collections.
|
||||||
|
|
||||||
2007-06-09 Fred Kiefer <FredKiefer@gmx.de>
|
2007-06-09 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
* Source/NSPredicate.m: Improved predicate parsing.
|
* Source/NSPredicate.m: Improved predicate parsing.
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
modify it under the terms of the GNU Library General Public
|
modify it under the terms of the GNU Library General Public
|
||||||
License as published by the Free Software Foundation; either
|
License as published by the Free Software Foundation; either
|
||||||
version 2 of the License, or (at your option) any later version.
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
This library is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
@ -75,6 +75,7 @@
|
||||||
- (NSExpression *) parseMultiplicationExpression;
|
- (NSExpression *) parseMultiplicationExpression;
|
||||||
- (NSExpression *) parseAdditionExpression;
|
- (NSExpression *) parseAdditionExpression;
|
||||||
- (NSExpression *) parseBinaryExpression;
|
- (NSExpression *) parseBinaryExpression;
|
||||||
|
- (NSExpression *) parseSimpleExpression;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -715,7 +716,14 @@
|
||||||
case NSGreaterThanOrEqualToPredicateOperatorType:
|
case NSGreaterThanOrEqualToPredicateOperatorType:
|
||||||
return ([leftResult compare: rightResult] != NSOrderedAscending);
|
return ([leftResult compare: rightResult] != NSOrderedAscending);
|
||||||
case NSEqualToPredicateOperatorType:
|
case NSEqualToPredicateOperatorType:
|
||||||
return [leftResult isEqual: rightResult];
|
if ([rightResult isKindOfClass: [NSString class]])
|
||||||
|
{
|
||||||
|
return [leftResult compare: rightResult options: compareOptions] == NSOrderedSame;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return [leftResult isEqual: rightResult];
|
||||||
|
}
|
||||||
case NSNotEqualToPredicateOperatorType:
|
case NSNotEqualToPredicateOperatorType:
|
||||||
return ![leftResult isEqual: rightResult];
|
return ![leftResult isEqual: rightResult];
|
||||||
case NSMatchesPredicateOperatorType:
|
case NSMatchesPredicateOperatorType:
|
||||||
|
@ -735,7 +743,27 @@
|
||||||
return ([leftResult compare: rightResult options: compareOptions range: range] == NSOrderedSame);
|
return ([leftResult compare: rightResult options: compareOptions range: range] == NSOrderedSame);
|
||||||
}
|
}
|
||||||
case NSInPredicateOperatorType:
|
case NSInPredicateOperatorType:
|
||||||
// FIXME: Handle special case where rightResult is a collection and leftResult an element of it.
|
// Handle special case where rightResult is a collection and leftResult an element of it.
|
||||||
|
if (![rightResult isKindOfClass: [NSString class]])
|
||||||
|
{
|
||||||
|
NSEnumerator *e;
|
||||||
|
id value;
|
||||||
|
|
||||||
|
if (![rightResult respondsToSelector: @selector(objectEnumerator)])
|
||||||
|
{
|
||||||
|
[NSException raise: NSInvalidArgumentException
|
||||||
|
format: @"The right hand side for an IN operator must be a collection"];
|
||||||
|
}
|
||||||
|
|
||||||
|
e = [rightResult objectEnumerator];
|
||||||
|
while ((value = [e nextObject]))
|
||||||
|
{
|
||||||
|
if ([value isEqual: leftResult])
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
return ([leftResult rangeOfString: rightResult options: compareOptions].location != NSNotFound);
|
return ([leftResult rangeOfString: rightResult options: compareOptions].location != NSNotFound);
|
||||||
case NSCustomSelectorPredicateOperatorType:
|
case NSCustomSelectorPredicateOperatorType:
|
||||||
{
|
{
|
||||||
|
@ -1506,7 +1534,8 @@
|
||||||
{
|
{
|
||||||
NSPredicate *l = [self parseOr];
|
NSPredicate *l = [self parseOr];
|
||||||
|
|
||||||
while ([self scanPredicateKeyword: @"AND"])
|
while ([self scanPredicateKeyword: @"AND"] ||
|
||||||
|
[self scanPredicateKeyword: @"&&"])
|
||||||
{
|
{
|
||||||
NSPredicate *r = [self parseOr];
|
NSPredicate *r = [self parseOr];
|
||||||
|
|
||||||
|
@ -1540,7 +1569,7 @@
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
l = [NSCompoundPredicate andPredicateWithSubpredicates:
|
l = [NSCompoundPredicate andPredicateWithSubpredicates:
|
||||||
[NSArray arrayWithObjects:l, r, nil]];
|
[NSArray arrayWithObjects: l, r, nil]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
|
@ -1583,7 +1612,8 @@
|
||||||
{
|
{
|
||||||
NSPredicate *l = [self parseNot];
|
NSPredicate *l = [self parseNot];
|
||||||
|
|
||||||
while ([self scanPredicateKeyword: @"OR"])
|
while ([self scanPredicateKeyword: @"OR"] ||
|
||||||
|
[self scanPredicateKeyword: @"||"])
|
||||||
{
|
{
|
||||||
NSPredicate *r = [self parseNot];
|
NSPredicate *r = [self parseNot];
|
||||||
|
|
||||||
|
@ -1656,7 +1686,8 @@
|
||||||
{
|
{
|
||||||
type = NSLessThanPredicateOperatorType;
|
type = NSLessThanPredicateOperatorType;
|
||||||
}
|
}
|
||||||
else if ([self scanString: @"<=" intoString: NULL])
|
else if ([self scanString: @"<=" intoString: NULL] ||
|
||||||
|
[self scanString: @"=<" intoString: NULL])
|
||||||
{
|
{
|
||||||
type = NSLessThanOrEqualToPredicateOperatorType;
|
type = NSLessThanOrEqualToPredicateOperatorType;
|
||||||
}
|
}
|
||||||
|
@ -1664,7 +1695,8 @@
|
||||||
{
|
{
|
||||||
type = NSGreaterThanPredicateOperatorType;
|
type = NSGreaterThanPredicateOperatorType;
|
||||||
}
|
}
|
||||||
else if ([self scanString: @">=" intoString: NULL])
|
else if ([self scanString: @">=" intoString: NULL] ||
|
||||||
|
[self scanString: @"=>" intoString: NULL])
|
||||||
{
|
{
|
||||||
type = NSGreaterThanOrEqualToPredicateOperatorType;
|
type = NSGreaterThanOrEqualToPredicateOperatorType;
|
||||||
}
|
}
|
||||||
|
@ -1673,7 +1705,8 @@
|
||||||
{
|
{
|
||||||
type = NSEqualToPredicateOperatorType;
|
type = NSEqualToPredicateOperatorType;
|
||||||
}
|
}
|
||||||
else if ([self scanString: @"!=" intoString: NULL])
|
else if ([self scanString: @"!=" intoString: NULL] ||
|
||||||
|
[self scanString: @"<>" intoString: NULL])
|
||||||
{
|
{
|
||||||
type = NSNotEqualToPredicateOperatorType;
|
type = NSNotEqualToPredicateOperatorType;
|
||||||
}
|
}
|
||||||
|
@ -1693,17 +1726,43 @@
|
||||||
{
|
{
|
||||||
type = NSEndsWithPredicateOperatorType;
|
type = NSEndsWithPredicateOperatorType;
|
||||||
}
|
}
|
||||||
else if ([self scanPredicateKeyword: @"IN"])
|
else if ([self scanPredicateKeyword: @"IN"] ||
|
||||||
|
[self scanPredicateKeyword: @"CONTAINS"])
|
||||||
{
|
{
|
||||||
type = NSInPredicateOperatorType;
|
type = NSInPredicateOperatorType;
|
||||||
}
|
}
|
||||||
else if ([self scanPredicateKeyword: @"BETWEEN"])
|
else if ([self scanPredicateKeyword: @"BETWEEN"])
|
||||||
{
|
{
|
||||||
// FIXME: Requires special handling to transfer into AND of
|
// Requires special handling to transfer into AND of
|
||||||
// two normal comparison predicates
|
// two normal comparison predicates
|
||||||
|
NSExpression *exp = [self parseSimpleExpression];
|
||||||
|
NSArray *a = (NSArray *)[exp constantValue];
|
||||||
|
NSNumber *lower, *upper;
|
||||||
|
NSExpression *lexp, *uexp;
|
||||||
|
NSPredicate *lp, *up;
|
||||||
|
|
||||||
[NSException raise: NSInvalidArgumentException
|
if (![a isKindOfClass: [NSArray class]])
|
||||||
format: @"Support for BETWEEN operator is missing"];
|
{
|
||||||
|
[NSException raise: NSInvalidArgumentException
|
||||||
|
format: @"BETWEEN operator requires array argument"];
|
||||||
|
}
|
||||||
|
|
||||||
|
lower = [a objectAtIndex: 0];
|
||||||
|
upper = [a objectAtIndex: 1];
|
||||||
|
lexp = [NSExpression expressionForConstantValue: lower];
|
||||||
|
uexp = [NSExpression expressionForConstantValue: upper];
|
||||||
|
lp = [NSComparisonPredicate predicateWithLeftExpression: left
|
||||||
|
rightExpression: lexp
|
||||||
|
modifier: modifier
|
||||||
|
type: NSGreaterThanPredicateOperatorType
|
||||||
|
options: opts];
|
||||||
|
up = [NSComparisonPredicate predicateWithLeftExpression: left
|
||||||
|
rightExpression: uexp
|
||||||
|
modifier: modifier
|
||||||
|
type: NSLessThanPredicateOperatorType
|
||||||
|
options: opts];
|
||||||
|
return [NSCompoundPredicate andPredicateWithSubpredicates:
|
||||||
|
[NSArray arrayWithObjects: lp, up, nil]];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1779,8 +1838,7 @@
|
||||||
if ([self scanString: @"}" intoString: NULL])
|
if ([self scanString: @"}" intoString: NULL])
|
||||||
{
|
{
|
||||||
// empty
|
// empty
|
||||||
// FIXME
|
return [NSExpression expressionForConstantValue: a];
|
||||||
return nil;
|
|
||||||
}
|
}
|
||||||
// first element
|
// first element
|
||||||
[a addObject: [self parseExpression]];
|
[a addObject: [self parseExpression]];
|
||||||
|
@ -1795,8 +1853,7 @@
|
||||||
[NSException raise: NSInvalidArgumentException
|
[NSException raise: NSInvalidArgumentException
|
||||||
format: @"Missing } in aggregate"];
|
format: @"Missing } in aggregate"];
|
||||||
}
|
}
|
||||||
// FIXME
|
return [NSExpression expressionForConstantValue: a];
|
||||||
return nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([self scanPredicateKeyword: @"NULL"] ||
|
if ([self scanPredicateKeyword: @"NULL"] ||
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue