Skip to content

Commit 98e5faf

Browse files
authored
feat: Add support to exclude PFObject fields in query results with PFQuery.excludeKeys (#1731)
1 parent 19c8a62 commit 98e5faf

File tree

12 files changed

+118
-1
lines changed

12 files changed

+118
-1
lines changed

Parse/Parse/Internal/Commands/PFRESTQueryCommand.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ NS_ASSUME_NONNULL_BEGIN
2828
conditions:(nullable NSDictionary *)conditions
2929
selectedKeys:(nullable NSSet *)selectedKeys
3030
includedKeys:(nullable NSSet *)includedKeys
31+
excludedKeys:(nullable NSSet *)excludedKeys
3132
limit:(NSInteger)limit
3233
skip:(NSInteger)skip
3334
explain:(BOOL)explain
@@ -54,6 +55,7 @@ NS_ASSUME_NONNULL_BEGIN
5455
conditions:(nullable NSDictionary *)conditions
5556
selectedKeys:(nullable NSSet *)selectedKeys
5657
includedKeys:(nullable NSSet *)includedKeys
58+
excludedKeys:(nullable NSSet *)excludedKeys
5759
limit:(NSInteger)limit
5860
skip:(NSInteger)skip
5961
explain:(BOOL)explain

Parse/Parse/Internal/Commands/PFRESTQueryCommand.m

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ + (nullable instancetype)findCommandForClassWithName:(NSString *)className
3636
conditions:(NSDictionary *)conditions
3737
selectedKeys:(NSSet *)selectedKeys
3838
includedKeys:(NSSet *)includedKeys
39+
excludedKeys:(NSSet *)excludedKeys
3940
limit:(NSInteger)limit
4041
skip:(NSInteger)skip
4142
explain:(BOOL)explain
@@ -48,6 +49,7 @@ + (nullable instancetype)findCommandForClassWithName:(NSString *)className
4849
conditions:conditions
4950
selectedKeys:selectedKeys
5051
includedKeys:includedKeys
52+
excludedKeys:excludedKeys
5153
limit:limit
5254
skip:skip
5355
explain:explain
@@ -102,6 +104,7 @@ + (nullable NSDictionary *)findCommandParametersForQueryState:(PFQueryState *)qu
102104
conditions:queryState.conditions
103105
selectedKeys:queryState.selectedKeys
104106
includedKeys:queryState.includedKeys
107+
excludedKeys:queryState.excludedKeys
105108
limit:queryState.limit
106109
skip:queryState.skip
107110
explain:queryState.explain
@@ -115,6 +118,7 @@ + (nullable NSDictionary *)findCommandParametersWithOrder:(NSString *)order
115118
conditions:(NSDictionary *)conditions
116119
selectedKeys:(NSSet *)selectedKeys
117120
includedKeys:(NSSet *)includedKeys
121+
excludedKeys:(NSSet *)excludedKeys
118122
limit:(NSInteger)limit
119123
skip:(NSInteger)skip
120124
explain:(BOOL)explain
@@ -137,6 +141,11 @@ + (nullable NSDictionary *)findCommandParametersWithOrder:(NSString *)order
137141
NSArray *keysArray = [includedKeys sortedArrayUsingDescriptors:sortDescriptors];
138142
parameters[@"include"] = [keysArray componentsJoinedByString:@","];
139143
}
144+
if (excludedKeys.count > 0) {
145+
NSArray *sortDescriptors = @[ [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:YES selector:@selector(compare:)] ];
146+
NSArray *keysArray = [excludedKeys sortedArrayUsingDescriptors:sortDescriptors];
147+
parameters[@"excludedKeys"] = [keysArray componentsJoinedByString:@","];
148+
}
140149
if (limit >= 0) {
141150
parameters[@"limit"] = [NSString stringWithFormat:@"%d", (int)limit];
142151
}
@@ -171,12 +180,14 @@ + (nullable NSDictionary *)findCommandParametersWithOrder:(NSString *)order
171180
PFParameterAssert(subquery.state.skip == 0, @"OR queries do not support sub queries with skip");
172181
PFParameterAssert(subquery.state.sortKeys.count == 0, @"OR queries do not support sub queries with order");
173182
PFParameterAssert(subquery.state.includedKeys.count == 0, @"OR queries do not support sub-queries with includes");
183+
PFParameterAssert(subquery.state.excludedKeys.count == 0, @"OR queries do not support sub-queries with excludeKeys");
174184
PFParameterAssert(subquery.state.selectedKeys == nil, @"OR queries do not support sub-queries with selectKeys");
175185

176186
NSDictionary *queryDict = [self findCommandParametersWithOrder:subquery.state.sortOrderString
177187
conditions:subquery.state.conditions
178188
selectedKeys:subquery.state.selectedKeys
179189
includedKeys:subquery.state.includedKeys
190+
excludedKeys:subquery.state.excludedKeys
180191
limit:subquery.state.limit
181192
skip:subquery.state.skip
182193
explain:subquery.state.explain
@@ -240,6 +251,7 @@ + (nullable id)_encodeSubqueryIfNeeded:(id)object error:(NSError * __autoreleasi
240251
conditions:subquery.state.conditions
241252
selectedKeys:subquery.state.selectedKeys
242253
includedKeys:subquery.state.includedKeys
254+
excludedKeys:subquery.state.excludedKeys
243255
limit:subquery.state.limit
244256
skip:subquery.state.skip
245257
explain:subquery.state.explain

Parse/Parse/Internal/Query/State/PFMutableQueryState.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@
7070
- (void)includeKey:(NSString *)key;
7171
- (void)includeKeys:(NSArray<NSString *> *)keys;
7272

73+
///--------------------------------------
74+
#pragma mark - Excludes
75+
///--------------------------------------
76+
77+
- (void)excludeKey:(NSString *)key;
78+
- (void)excludeKeys:(NSArray<NSString *> *)keys;
79+
7380
///--------------------------------------
7481
#pragma mark - Selected Keys
7582
///--------------------------------------

Parse/Parse/Internal/Query/State/PFMutableQueryState.m

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ @interface PFMutableQueryState () {
1717
NSMutableDictionary<NSString *, id> *_conditions;
1818
NSMutableArray<NSString *> *_sortKeys;
1919
NSMutableSet<NSString *> *_includedKeys;
20+
NSMutableSet<NSString *> *_excludedKeys;
2021
NSMutableDictionary<NSString *, NSString *> *_extraOptions;
2122
}
2223

@@ -27,6 +28,7 @@ @implementation PFMutableQueryState
2728
@synthesize conditions = _conditions;
2829
@synthesize sortKeys = _sortKeys;
2930
@synthesize includedKeys = _includedKeys;
31+
@synthesize excludedKeys = _excludedKeys;
3032
@synthesize extraOptions = _extraOptions;
3133

3234
@dynamic parseClassName;
@@ -53,6 +55,7 @@ + (NSDictionary *)propertyAttributes {
5355
attributes[PFQueryStatePropertyName(conditions)] = [PFPropertyAttributes attributesWithAssociationType:PFPropertyInfoAssociationTypeMutableCopy];
5456
attributes[PFQueryStatePropertyName(sortKeys)] = [PFPropertyAttributes attributesWithAssociationType:PFPropertyInfoAssociationTypeMutableCopy];
5557
attributes[PFQueryStatePropertyName(includedKeys)] = [PFPropertyAttributes attributesWithAssociationType:PFPropertyInfoAssociationTypeMutableCopy];
58+
attributes[PFQueryStatePropertyName(excludedKeys)] = [PFPropertyAttributes attributesWithAssociationType:PFPropertyInfoAssociationTypeMutableCopy];
5659
attributes[PFQueryStatePropertyName(extraOptions)] = [PFPropertyAttributes attributesWithAssociationType:PFPropertyInfoAssociationTypeMutableCopy];
5760

5861
return attributes;
@@ -163,6 +166,26 @@ - (void)includeKeys:(NSArray<NSString *> *)keys {
163166
}
164167
}
165168

169+
///--------------------------------------
170+
#pragma mark - Excludes
171+
///--------------------------------------
172+
173+
- (void)excludeKey:(NSString *)key {
174+
if (!_excludedKeys) {
175+
_excludedKeys = [NSMutableSet setWithObject:key];
176+
} else {
177+
[_excludedKeys addObject:key];
178+
}
179+
}
180+
181+
- (void)excludeKeys:(NSArray<NSString *> *)keys {
182+
if (!_excludedKeys) {
183+
_excludedKeys = [NSMutableSet setWithArray:keys];
184+
} else {
185+
[_excludedKeys addObjectsFromArray:keys];
186+
}
187+
}
188+
166189
///--------------------------------------
167190
#pragma mark - Selected Keys
168191
///--------------------------------------

Parse/Parse/Internal/Query/State/PFQueryState.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
@property (nonatomic, copy, readonly) NSString *sortOrderString;
2424

2525
@property (nonatomic, copy, readonly) NSSet<NSString *> *includedKeys;
26+
@property (nonatomic, copy, readonly) NSSet<NSString *> *excludedKeys;
2627
@property (nonatomic, copy, readonly) NSSet<NSString *> *selectedKeys;
2728
@property (nonatomic, copy, readonly) NSDictionary<NSString *, NSString *> *extraOptions;
2829

Parse/Parse/Internal/Query/State/PFQueryState.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ + (NSDictionary *)propertyAttributes {
2626
PFQueryStatePropertyName(conditions): [PFPropertyAttributes attributesWithAssociationType:PFPropertyInfoAssociationTypeCopy],
2727
PFQueryStatePropertyName(sortKeys): [PFPropertyAttributes attributesWithAssociationType:PFPropertyInfoAssociationTypeCopy],
2828
PFQueryStatePropertyName(includedKeys): [PFPropertyAttributes attributesWithAssociationType:PFPropertyInfoAssociationTypeCopy],
29+
PFQueryStatePropertyName(excludedKeys): [PFPropertyAttributes attributesWithAssociationType:PFPropertyInfoAssociationTypeCopy],
2930
PFQueryStatePropertyName(selectedKeys): [PFPropertyAttributes attributesWithAssociationType:PFPropertyInfoAssociationTypeCopy],
3031
PFQueryStatePropertyName(extraOptions): [PFPropertyAttributes attributesWithAssociationType:PFPropertyInfoAssociationTypeCopy],
3132

Parse/Parse/Internal/Query/State/PFQueryState_Private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
NSArray<NSString *> *_sortKeys;
3030

3131
NSSet<NSString *> *_includedKeys;
32+
NSSet<NSString *> *_excludedKeys;
3233
NSSet<NSString *> *_selectedKeys;
3334
NSDictionary<NSString *, NSString *> *_extraOptions;
3435

Parse/Parse/Source/PFQuery.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,28 @@ typedef void (^PFQueryArrayResultBlock)(NSArray<PFGenericObject> *_Nullable obje
107107
*/
108108
- (instancetype)includeKeys:(NSArray<NSString *> *)keys;
109109

110+
/**
111+
Make the query restrict the fields of the returned `PFObject`s to exclude the provided key.
112+
113+
If this is called multiple times, then all of the keys specified in each of the calls will be excluded.
114+
115+
@param key The key to exclude in the result.
116+
117+
@return The same instance of `PFQuery` as the receiver. This allows method chaining.
118+
*/
119+
- (instancetype)excludeKey:(NSString *)key;
120+
121+
/**
122+
Make the query restrict the fields of the returned `PFObject`s to exclude the provided keys.
123+
124+
If this is called multiple times, then all of the keys specified in each of the calls will be excluded.
125+
126+
@param keys The keys to exclude in the result.
127+
128+
@return The same instance of `PFQuery` as the receiver. This allows method chaining.
129+
*/
130+
- (instancetype)excludeKeys:(NSArray<NSString *> *)keys;
131+
110132
/**
111133
Make the query restrict the fields of the returned `PFObject`s to include only the provided keys.
112134

Parse/Parse/Source/PFQuery.m

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,22 @@ - (instancetype)includeKeys:(NSArray<NSString *> *)keys {
426426
return self;
427427
}
428428

429+
///--------------------------------------
430+
#pragma mark - Exclude
431+
///--------------------------------------
432+
433+
- (instancetype)excludeKey:(NSString *)key {
434+
[self checkIfCommandIsRunning];
435+
[self.state excludeKey:key];
436+
return self;
437+
}
438+
439+
- (instancetype)excludeKeys:(NSArray<NSString *> *)keys {
440+
[self checkIfCommandIsRunning];
441+
[self.state excludeKeys:keys];
442+
return self;
443+
}
444+
429445
///--------------------------------------
430446
#pragma mark - Select
431447
///--------------------------------------

Parse/Tests/Other/TestCases/UnitTestCase/PFUnitTestCase.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ - (void)setUp {
3737

3838
[Parse setApplicationId:self.applicationId clientKey:self.clientKey];
3939

40-
[self waitForExpectations:@[expect] timeout:10];
40+
[self waitForExpectations:@[expect] timeout:30];
4141
}
4242

4343
- (void)tearDown {

Parse/Tests/Unit/QueryStateUnitTests.m

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ - (PFQueryState *)sampleQueryState {
4141
[state sortByKey:@"a" ascending:NO];
4242

4343
[state includeKey:@"yolo"];
44+
[state excludeKey:@"yolo"];
4445
[state selectKeys:@[ @"yolo" ]];
4546
[state redirectClassNameForKey:@"ABC"];
4647
return state;
@@ -62,6 +63,7 @@ - (void)assertQueryState:(PFQueryState *)state equalToState:(PFQueryState *)diff
6263
XCTAssertEqualObjects(state.sortKeys, differentState.sortKeys);
6364
XCTAssertEqualObjects(state.sortOrderString, differentState.sortOrderString);
6465
XCTAssertEqualObjects(state.includedKeys, differentState.includedKeys);
66+
XCTAssertEqualObjects(state.excludedKeys, differentState.excludedKeys);
6567
XCTAssertEqualObjects(state.selectedKeys, differentState.selectedKeys);
6668
XCTAssertEqualObjects(state.extraOptions, differentState.extraOptions);
6769

@@ -213,6 +215,23 @@ - (void)testIncludeMultipleKeys {
213215
XCTAssertEqualObjects(state.includedKeys, includedKeys);
214216
}
215217

218+
- (void)testExcludeKeys {
219+
PFMutableQueryState *state = [[PFMutableQueryState alloc] initWithParseClassName:@"Yarr"];
220+
[state excludeKey:@"a"];
221+
[state excludeKey:@"b"];
222+
223+
NSSet *excludedKeys = PF_SET(@"a", @"b");
224+
XCTAssertEqualObjects(state.excludedKeys, excludedKeys);
225+
}
226+
227+
- (void)testExcludeMultipleKeys {
228+
PFMutableQueryState *state = [[PFMutableQueryState alloc] initWithParseClassName:@"Yarr"];
229+
[state excludeKeys:@[ @"a", @"b", @"c" ]];
230+
231+
NSSet *excludedKeys = PF_SET(@"a", @"b", @"c");
232+
XCTAssertEqualObjects(state.excludedKeys, excludedKeys);
233+
}
234+
216235
- (void)testSelectKeys {
217236
PFMutableQueryState *state = [[PFMutableQueryState alloc] initWithParseClassName:@"Yarr"];
218237

Parse/Tests/Unit/QueryUnitTests.m

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,17 @@ - (void)testIncludeKey {
261261
XCTAssertTrue([query.state.includedKeys containsObject:@"yolo1"]);
262262
}
263263

264+
- (void)testExcludeKey {
265+
PFQuery *query = [PFQuery queryWithClassName:@"a"];
266+
[query excludeKey:@"yolo"];
267+
XCTAssertEqualObjects(query.state.excludedKeys, (PF_SET(@"yolo")));
268+
269+
[query excludeKey:@"yolo1"];
270+
XCTAssertEqualObjects(query.state.excludedKeys, (PF_SET(@"yolo", @"yolo1")));
271+
XCTAssertTrue([query.state.excludedKeys containsObject:@"yolo"]);
272+
XCTAssertTrue([query.state.excludedKeys containsObject:@"yolo1"]);
273+
}
274+
264275
- (void)testSelectKeys {
265276
PFQuery *query = [PFQuery queryWithClassName:@"a"];
266277
[query selectKeys:@[ @"a", @"a" ]];
@@ -1320,6 +1331,7 @@ - (void)testNSCopying {
13201331
[query orderByAscending:@"b"];
13211332
[query includeKey:@"c"];
13221333
[query selectKeys:@[ @"d" ]];
1334+
[query excludeKeys:@[ @"f" ]];
13231335
[query redirectClassNameForKey:@"e"];
13241336

13251337
query.limit = 10;
@@ -1338,6 +1350,7 @@ - (void)testNSCopying {
13381350
XCTAssertEqualObjects(queryCopy.state.conditions[@"a"], query.state.conditions[@"a"]);
13391351
XCTAssertEqualObjects(queryCopy.state.sortOrderString, query.state.sortOrderString);
13401352
XCTAssertEqualObjects([queryCopy.state.includedKeys anyObject], [query.state.includedKeys anyObject]);
1353+
XCTAssertEqualObjects([queryCopy.state.excludedKeys anyObject], [query.state.excludedKeys anyObject]);
13411354
XCTAssertEqualObjects([queryCopy.state.selectedKeys anyObject], [query.state.selectedKeys anyObject]);
13421355
XCTAssertEqualObjects([[queryCopy.state.extraOptions allValues] lastObject],
13431356
[[query.state.extraOptions allValues] lastObject]);

0 commit comments

Comments
 (0)