Skip to content

Commit 2316a3f

Browse files
authored
feat: Add support for PFQuery.containedBy (#1735)
1 parent bca26ff commit 2316a3f

File tree

7 files changed

+74
-0
lines changed

7 files changed

+74
-0
lines changed

Parse/Parse/Internal/LocalDataStore/OfflineQueryLogic/PFOfflineQueryLogic.m

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,19 @@ + (BOOL)matchesValue:(id)value containsAllObjectsInArray:(id)constraints {
329329
return YES;
330330
}
331331

332+
/**
333+
Matches $containedBy constraints.
334+
*/
335+
+ (BOOL)matchesValue:(NSArray *)values
336+
containedBy:(NSArray *)constraints {
337+
for (id value in values) {
338+
if (![self matchesValue:value containedIn:constraints]) {
339+
return NO;
340+
}
341+
}
342+
return YES;
343+
}
344+
332345
/**
333346
Matches $regex constraints.
334347
*/
@@ -446,6 +459,8 @@ + (BOOL)matchesValue:(id)value
446459
return [self matchesValue:value notContainedIn:constraint];
447460
} else if ([operator isEqualToString:PFQueryKeyContainsAll]) {
448461
return [self matchesValue:value containsAllObjectsInArray:constraint];
462+
} else if ([operator isEqualToString:PFQueryKeyContainedBy]) {
463+
return [self matchesValue:value containedBy:constraint];
449464
} else if ([operator isEqualToString:PFQueryKeyRegex]) {
450465
return [self matchesValue:value regex:constraint withOptions:allKeyConstraints[PFQueryOptionKeyRegexOptions]];
451466
} else if ([operator isEqualToString:PFQueryOptionKeyRegexOptions]) {

Parse/Parse/Internal/Query/PFQueryConstants.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ extern NSString *const PFQueryKeyGreaterThanOrEqualTo;
1919
extern NSString *const PFQueryKeyContainedIn;
2020
extern NSString *const PFQueryKeyNotContainedIn;
2121
extern NSString *const PFQueryKeyContainsAll;
22+
extern NSString *const PFQueryKeyContainedBy;
2223
extern NSString *const PFQueryKeyNearSphere;
2324
extern NSString *const PFQueryKeyWithin;
2425
extern NSString *const PFQueryKeyGeoWithin;

Parse/Parse/Internal/Query/PFQueryConstants.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
NSString *const PFQueryKeyContainedIn = @"$in";
1818
NSString *const PFQueryKeyNotContainedIn = @"$nin";
1919
NSString *const PFQueryKeyContainsAll = @"$all";
20+
NSString *const PFQueryKeyContainedBy = @"$containedBy";
2021
NSString *const PFQueryKeyNearSphere = @"$nearSphere";
2122
NSString *const PFQueryKeyWithin = @"$within";
2223
NSString *const PFQueryKeyGeoWithin = @"$geoWithin";

Parse/Parse/Source/PFQuery.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,17 @@ typedef void (^PFQueryArrayResultBlock)(NSArray<PFGenericObject> *_Nullable obje
273273
*/
274274
- (instancetype)whereKey:(NSString *)key containsAllObjectsInArray:(NSArray *)array;
275275

276+
/**
277+
Adds a constraint to the query that requires a particular key's value to
278+
be contained by the provided list of values. Get objects where all array elements match
279+
280+
@param key The key to be constrained.
281+
@param array The array of values to search for.
282+
283+
@return The same instance of `PFQuery` as the receiver. This allows method chaining.
284+
*/
285+
- (instancetype)whereKey:(NSString *)key containedBy:(NSArray *)array;
286+
276287
///--------------------------------------
277288
#pragma mark - Adding Location Constraints
278289
///--------------------------------------

Parse/Parse/Source/PFQuery.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,10 @@ - (instancetype)whereKey:(NSString *)key containsAllObjectsInArray:(NSArray *)ar
303303
return [self whereKey:key condition:PFQueryKeyContainsAll object:array];
304304
}
305305

306+
- (instancetype)whereKey:(NSString *)key containedBy:(NSArray *)inArray {
307+
return [self whereKey:key condition:PFQueryKeyContainedBy object:inArray];
308+
}
309+
306310
- (instancetype)whereKey:(NSString *)key nearGeoPoint:(PFGeoPoint *)geopoint {
307311
return [self whereKey:key condition:PFQueryKeyNearSphere object:geopoint];
308312
}

Parse/Tests/Unit/OfflineQueryLogicUnitTests.m

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,42 @@ - (void)testQueryAll {
10971097
[task waitUntilFinished];
10981098
}
10991099

1100+
- (void)testQueryContainedBy {
1101+
PFOfflineQueryLogic *logic = [[PFOfflineQueryLogic alloc] init];
1102+
PFSQLiteDatabase *database = [[PFSQLiteDatabase alloc] init];
1103+
1104+
PFObject *object = [PFObject objectWithClassName:@"Object"];
1105+
object[@"numbers"] = @[@0, @2];
1106+
object[@"letters"] = @[@"b", @"c", @"d"];
1107+
PFQuery *query = [PFQuery queryWithClassName:@"Object"];
1108+
BFTask *task = [BFTask taskWithResult:nil];
1109+
1110+
[query whereKey:@"numbers" containedBy:@[@1, @2, @3, @4]];
1111+
PFConstraintMatcherBlock matcherBlock = [logic createMatcherForQueryState:query.state user:_user];
1112+
1113+
// Check matcher
1114+
task = [[task continueWithBlock:^id(BFTask *task) {
1115+
return matcherBlock(object, database);
1116+
}] continueWithBlock:^id(BFTask *task) {
1117+
XCTAssertFalse([task.result boolValue]);
1118+
return nil;
1119+
}];
1120+
1121+
query = [PFQuery queryWithClassName:@"Object"];
1122+
[query whereKey:@"letters" containedBy:@[@"a", @"b", @"c", @"d", @"e"]];
1123+
matcherBlock = [logic createMatcherForQueryState:query.state user:_user];
1124+
1125+
// Check matcher
1126+
task = [[task continueWithBlock:^id(BFTask *task) {
1127+
return matcherBlock(object, database);
1128+
}] continueWithBlock:^id(BFTask *task) {
1129+
XCTAssertTrue([task.result boolValue]);
1130+
return nil;
1131+
}];
1132+
1133+
[task waitUntilFinished];
1134+
}
1135+
11001136
- (void)testQueryRegex {
11011137
PFOfflineQueryLogic *logic = [[PFOfflineQueryLogic alloc] init];
11021138
PFSQLiteDatabase *database = [[PFSQLiteDatabase alloc] init];

Parse/Tests/Unit/QueryUnitTests.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,12 @@ - (void)testWhereContainsAllObjectsInArray {
426426
XCTAssertEqualObjects(query.state.conditions, @{ @"yolo" : @{@"$all" : @[ @"yarr" ]} });
427427
}
428428

429+
- (void)testWhereContainedBy {
430+
PFQuery *query = [PFQuery queryWithClassName:@"a"];
431+
[query whereKey:@"yolo" containedBy:@[ @"yarr" ]];
432+
XCTAssertEqualObjects(query.state.conditions, @{ @"yolo" : @{@"$containedBy" : @[ @"yarr" ]} });
433+
}
434+
429435
- (void)testWhereKeyNearGeoPoint {
430436
PFGeoPoint *geoPoint = [PFGeoPoint geoPointWithLatitude:10.0 longitude:20.0];
431437

0 commit comments

Comments
 (0)