Skip to content

Commit

Permalink
feat: Add support for PFQuery.containedBy (parse-community#1735)
Browse files Browse the repository at this point in the history
  • Loading branch information
dplewis authored Jul 20, 2023
1 parent bca26ff commit 2316a3f
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,19 @@ + (BOOL)matchesValue:(id)value containsAllObjectsInArray:(id)constraints {
return YES;
}

/**
Matches $containedBy constraints.
*/
+ (BOOL)matchesValue:(NSArray *)values
containedBy:(NSArray *)constraints {
for (id value in values) {
if (![self matchesValue:value containedIn:constraints]) {
return NO;
}
}
return YES;
}

/**
Matches $regex constraints.
*/
Expand Down Expand Up @@ -446,6 +459,8 @@ + (BOOL)matchesValue:(id)value
return [self matchesValue:value notContainedIn:constraint];
} else if ([operator isEqualToString:PFQueryKeyContainsAll]) {
return [self matchesValue:value containsAllObjectsInArray:constraint];
} else if ([operator isEqualToString:PFQueryKeyContainedBy]) {
return [self matchesValue:value containedBy:constraint];
} else if ([operator isEqualToString:PFQueryKeyRegex]) {
return [self matchesValue:value regex:constraint withOptions:allKeyConstraints[PFQueryOptionKeyRegexOptions]];
} else if ([operator isEqualToString:PFQueryOptionKeyRegexOptions]) {
Expand Down
1 change: 1 addition & 0 deletions Parse/Parse/Internal/Query/PFQueryConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ extern NSString *const PFQueryKeyGreaterThanOrEqualTo;
extern NSString *const PFQueryKeyContainedIn;
extern NSString *const PFQueryKeyNotContainedIn;
extern NSString *const PFQueryKeyContainsAll;
extern NSString *const PFQueryKeyContainedBy;
extern NSString *const PFQueryKeyNearSphere;
extern NSString *const PFQueryKeyWithin;
extern NSString *const PFQueryKeyGeoWithin;
Expand Down
1 change: 1 addition & 0 deletions Parse/Parse/Internal/Query/PFQueryConstants.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
NSString *const PFQueryKeyContainedIn = @"$in";
NSString *const PFQueryKeyNotContainedIn = @"$nin";
NSString *const PFQueryKeyContainsAll = @"$all";
NSString *const PFQueryKeyContainedBy = @"$containedBy";
NSString *const PFQueryKeyNearSphere = @"$nearSphere";
NSString *const PFQueryKeyWithin = @"$within";
NSString *const PFQueryKeyGeoWithin = @"$geoWithin";
Expand Down
11 changes: 11 additions & 0 deletions Parse/Parse/Source/PFQuery.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,17 @@ typedef void (^PFQueryArrayResultBlock)(NSArray<PFGenericObject> *_Nullable obje
*/
- (instancetype)whereKey:(NSString *)key containsAllObjectsInArray:(NSArray *)array;

/**
Adds a constraint to the query that requires a particular key's value to
be contained by the provided list of values. Get objects where all array elements match
@param key The key to be constrained.
@param array The array of values to search for.
@return The same instance of `PFQuery` as the receiver. This allows method chaining.
*/
- (instancetype)whereKey:(NSString *)key containedBy:(NSArray *)array;

///--------------------------------------
#pragma mark - Adding Location Constraints
///--------------------------------------
Expand Down
4 changes: 4 additions & 0 deletions Parse/Parse/Source/PFQuery.m
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,10 @@ - (instancetype)whereKey:(NSString *)key containsAllObjectsInArray:(NSArray *)ar
return [self whereKey:key condition:PFQueryKeyContainsAll object:array];
}

- (instancetype)whereKey:(NSString *)key containedBy:(NSArray *)inArray {
return [self whereKey:key condition:PFQueryKeyContainedBy object:inArray];
}

- (instancetype)whereKey:(NSString *)key nearGeoPoint:(PFGeoPoint *)geopoint {
return [self whereKey:key condition:PFQueryKeyNearSphere object:geopoint];
}
Expand Down
36 changes: 36 additions & 0 deletions Parse/Tests/Unit/OfflineQueryLogicUnitTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,42 @@ - (void)testQueryAll {
[task waitUntilFinished];
}

- (void)testQueryContainedBy {
PFOfflineQueryLogic *logic = [[PFOfflineQueryLogic alloc] init];
PFSQLiteDatabase *database = [[PFSQLiteDatabase alloc] init];

PFObject *object = [PFObject objectWithClassName:@"Object"];
object[@"numbers"] = @[@0, @2];
object[@"letters"] = @[@"b", @"c", @"d"];
PFQuery *query = [PFQuery queryWithClassName:@"Object"];
BFTask *task = [BFTask taskWithResult:nil];

[query whereKey:@"numbers" containedBy:@[@1, @2, @3, @4]];
PFConstraintMatcherBlock matcherBlock = [logic createMatcherForQueryState:query.state user:_user];

// Check matcher
task = [[task continueWithBlock:^id(BFTask *task) {
return matcherBlock(object, database);
}] continueWithBlock:^id(BFTask *task) {
XCTAssertFalse([task.result boolValue]);
return nil;
}];

query = [PFQuery queryWithClassName:@"Object"];
[query whereKey:@"letters" containedBy:@[@"a", @"b", @"c", @"d", @"e"]];
matcherBlock = [logic createMatcherForQueryState:query.state user:_user];

// Check matcher
task = [[task continueWithBlock:^id(BFTask *task) {
return matcherBlock(object, database);
}] continueWithBlock:^id(BFTask *task) {
XCTAssertTrue([task.result boolValue]);
return nil;
}];

[task waitUntilFinished];
}

- (void)testQueryRegex {
PFOfflineQueryLogic *logic = [[PFOfflineQueryLogic alloc] init];
PFSQLiteDatabase *database = [[PFSQLiteDatabase alloc] init];
Expand Down
6 changes: 6 additions & 0 deletions Parse/Tests/Unit/QueryUnitTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,12 @@ - (void)testWhereContainsAllObjectsInArray {
XCTAssertEqualObjects(query.state.conditions, @{ @"yolo" : @{@"$all" : @[ @"yarr" ]} });
}

- (void)testWhereContainedBy {
PFQuery *query = [PFQuery queryWithClassName:@"a"];
[query whereKey:@"yolo" containedBy:@[ @"yarr" ]];
XCTAssertEqualObjects(query.state.conditions, @{ @"yolo" : @{@"$containedBy" : @[ @"yarr" ]} });
}

- (void)testWhereKeyNearGeoPoint {
PFGeoPoint *geoPoint = [PFGeoPoint geoPointWithLatitude:10.0 longitude:20.0];

Expand Down

0 comments on commit 2316a3f

Please sign in to comment.