28
28
29
29
#include " Firestore/core/src/firebase/firestore/api/input_validation.h"
30
30
#include " Firestore/core/src/firebase/firestore/core/filter.h"
31
+ #include " Firestore/core/src/firebase/firestore/core/nan_filter.h"
32
+ #include " Firestore/core/src/firebase/firestore/core/null_filter.h"
31
33
#include " Firestore/core/src/firebase/firestore/core/query.h"
34
+ #include " Firestore/core/src/firebase/firestore/core/relation_filter.h"
32
35
#include " Firestore/core/src/firebase/firestore/model/document_key.h"
33
36
#include " Firestore/core/src/firebase/firestore/model/field_path.h"
34
37
#include " Firestore/core/src/firebase/firestore/model/field_value.h"
58
61
59
62
#pragma mark - Filter::Operator functions
60
63
61
- NSString *FSTStringFromQueryRelationOperator (Filter::Operator filterOperator) {
62
- switch (filterOperator) {
63
- case Filter::Operator::LessThan:
64
- return @" <" ;
65
- case Filter::Operator::LessThanOrEqual:
66
- return @" <=" ;
67
- case Filter::Operator::Equal:
68
- return @" ==" ;
69
- case Filter::Operator::GreaterThanOrEqual:
70
- return @" >=" ;
71
- case Filter::Operator::GreaterThan:
72
- return @" >" ;
73
- case Filter::Operator::ArrayContains:
74
- return @" array_contains" ;
75
- default :
76
- HARD_FAIL (" Unknown Filter::Operator %s" , filterOperator);
77
- }
78
- }
79
-
80
64
@implementation FSTFilter
81
65
82
66
+ (instancetype )filterWithField : (const FieldPath &)field
@@ -141,7 +125,7 @@ - (NSString *)canonicalID;
141
125
@end
142
126
143
127
@implementation FSTRelationFilter {
144
- FieldValue _value ;
128
+ core::RelationFilter _filter ;
145
129
}
146
130
147
131
#pragma mark - Constructor methods
@@ -151,202 +135,137 @@ - (instancetype)initWithField:(FieldPath)field
151
135
value : (FieldValue)value {
152
136
self = [super init ];
153
137
if (self) {
154
- _field = std::move (field);
155
- _filterOperator = filterOperator;
156
- _value = value;
138
+ _filter = core::RelationFilter (std::move (field), filterOperator, std::move (value));
157
139
}
158
140
return self;
159
141
}
160
142
161
143
#pragma mark - Public Methods
162
144
163
145
- (BOOL )isInequality {
164
- return self.filterOperator != Filter::Operator::Equal &&
165
- self.filterOperator != Filter::Operator::ArrayContains;
146
+ return _filter.IsInequality ();
166
147
}
167
148
168
- - (const firebase::firestore::model::FieldPath &)field {
169
- return _field;
149
+ - (const model::FieldPath &)field {
150
+ return _filter.field ();
151
+ }
152
+
153
+ - (core::Filter::Operator)filterOperator {
154
+ return _filter.op ();
155
+ }
156
+
157
+ - (const model::FieldValue &)value {
158
+ return _filter.value ();
170
159
}
171
160
172
161
#pragma mark - NSObject methods
173
162
174
163
- (NSString *)description {
175
- return [NSString stringWithFormat: @" %s %@ %s " , _field.CanonicalString ().c_str (),
176
- FSTStringFromQueryRelationOperator (self .filterOperator),
177
- self .value.ToString ().c_str ()];
164
+ return util::MakeNSString (_filter.ToString ());
178
165
}
179
166
180
167
- (BOOL )isEqual : (id )other {
181
- if (self == other) {
182
- return YES ;
183
- }
184
- if (![other isKindOfClass: [FSTRelationFilter class ]]) {
185
- return NO ;
186
- }
187
- return [self isEqualToFilter: (FSTRelationFilter *)other];
168
+ if (self == other) return YES ;
169
+ if (![other isKindOfClass: [FSTRelationFilter class ]]) return NO ;
170
+
171
+ return _filter == ((FSTRelationFilter *)other)->_filter ;
188
172
}
189
173
190
174
#pragma mark - Private methods
191
175
192
176
- (BOOL )matchesDocument : (FSTDocument *)document {
193
- if (_field.IsKeyFieldPath ()) {
194
- HARD_ASSERT (self.value .type () == FieldValue::Type::Reference,
195
- " Comparing on key, but filter value not a Reference." );
196
- HARD_ASSERT (self.filterOperator != Filter::Operator::ArrayContains,
197
- " arrayContains queries don't make sense on document keys." );
198
- const auto &ref = self.value .reference_value ();
199
- ComparisonResult comparison = document.key .CompareTo (ref.key ());
200
- return [self matchesComparison: comparison];
201
- } else {
202
- auto value = [document fieldForPath: self .field];
203
- if (!value) return false ;
204
-
205
- return [self matchesValue: *value];
206
- }
177
+ model::Document converted (document);
178
+ return _filter.Matches (converted);
207
179
}
208
180
209
181
- (NSString *)canonicalID {
210
- // TODO(b/37283291): This should be collision robust and avoid relying on |description| methods.
211
- return [NSString stringWithFormat: @" %s %@ %s " , _field.CanonicalString ().c_str (),
212
- FSTStringFromQueryRelationOperator (self .filterOperator),
213
- self .value.ToString ().c_str ()];
214
- }
215
-
216
- - (BOOL )isEqualToFilter : (FSTRelationFilter *)other {
217
- if (self.filterOperator != other.filterOperator ) {
218
- return NO ;
219
- }
220
- if (_field != other.field ) {
221
- return NO ;
222
- }
223
- return self.value == other.value ;
224
- }
225
-
226
- /* * Returns YES if receiver is true with the given value as its LHS. */
227
- - (BOOL )matchesValue : (const FieldValue &)other {
228
- if (self.filterOperator == Filter::Operator::ArrayContains) {
229
- if (other.type () == FieldValue::Type::Array) {
230
- const auto &array = other.array_value ();
231
- auto found = absl::c_find (array, self.value );
232
- return found != array.end ();
233
- } else {
234
- return false ;
235
- }
236
- } else {
237
- // Only perform comparison queries on types with matching backend order (such as double and
238
- // int).
239
- return FieldValue::Comparable (self.value .type (), other.type ()) &&
240
- [self matchesComparison: other.CompareTo (self .value)];
241
- }
242
- }
243
-
244
- - (BOOL )matchesComparison : (util::ComparisonResult)comparison {
245
- switch (self.filterOperator ) {
246
- case Filter::Operator::LessThan:
247
- return comparison == ComparisonResult::Ascending;
248
- case Filter::Operator::LessThanOrEqual:
249
- return comparison == ComparisonResult::Ascending || comparison == ComparisonResult::Same;
250
- case Filter::Operator::Equal:
251
- return comparison == ComparisonResult::Same;
252
- case Filter::Operator::GreaterThanOrEqual:
253
- return comparison == ComparisonResult::Descending || comparison == ComparisonResult::Same;
254
- case Filter::Operator::GreaterThan:
255
- return comparison == ComparisonResult::Descending;
256
- default :
257
- HARD_FAIL (" Unknown operator: %s" , self.filterOperator );
258
- }
182
+ return util::MakeNSString (_filter.CanonicalId ());
259
183
}
260
184
261
185
@end
262
186
263
187
#pragma mark - FSTNullFilter
264
188
265
- @interface FSTNullFilter () {
266
- FieldPath _field ;
189
+ @implementation FSTNullFilter {
190
+ core::NullFilter _filter ;
267
191
}
268
- @end
269
192
270
- @implementation FSTNullFilter
271
193
- (instancetype )initWithField : (FieldPath)field {
272
194
if (self = [super init ]) {
273
- _field = std::move (field);
195
+ _filter = core::NullFilter ( std::move (field) );
274
196
}
275
197
return self;
276
198
}
277
199
278
200
- (BOOL )matchesDocument : (FSTDocument *)document {
279
- absl::optional<FieldValue> fieldValue = [ document fieldForPath: self .field] ;
280
- return fieldValue && fieldValue-> type () == FieldValue::Type::Null ;
201
+ model::Document converted ( document) ;
202
+ return _filter. Matches (converted) ;
281
203
}
282
204
283
205
- (NSString *)canonicalID {
284
- return [ NSString stringWithFormat: @" %s IS NULL " , _field. CanonicalString (). c_str ()] ;
206
+ return util::MakeNSString (_filter. CanonicalId ()) ;
285
207
}
286
208
287
209
- (const firebase::firestore::model::FieldPath &)field {
288
- return _field ;
210
+ return _filter. field () ;
289
211
}
290
212
291
213
- (NSString *)description {
292
- return [ self canonicalID ] ;
214
+ return util::MakeNSString (_filter. ToString ()) ;
293
215
}
294
216
295
217
- (BOOL )isEqual : (id )other {
296
218
if (other == self) return YES ;
297
219
if (![[other class ] isEqual: [self class ]]) return NO ;
298
220
299
- return _field == ((FSTNullFilter *)other)->_field ;
221
+ return _filter == ((FSTNullFilter *)other)->_filter ;
300
222
}
301
223
302
224
- (NSUInteger )hash {
303
- return util:: Hash (_field );
225
+ return _filter. Hash ();
304
226
}
305
227
306
228
@end
307
229
308
230
#pragma mark - FSTNanFilter
309
231
310
- @interface FSTNanFilter () {
311
- FieldPath _field ;
232
+ @implementation FSTNanFilter {
233
+ core::NanFilter _filter ;
312
234
}
313
- @end
314
-
315
- @implementation FSTNanFilter
316
235
317
236
- (instancetype )initWithField : (FieldPath)field {
318
237
if (self = [super init ]) {
319
- _field = std::move (field);
238
+ _filter = core::NanFilter (field);
320
239
}
321
240
return self;
322
241
}
323
242
324
243
- (BOOL )matchesDocument : (FSTDocument *)document {
325
- absl::optional<FieldValue> fieldValue = [ document fieldForPath: self .field] ;
326
- return fieldValue && fieldValue-> is_nan ( );
244
+ model::Document converted ( document) ;
245
+ return _filter. Matches (converted );
327
246
}
328
247
329
248
- (NSString *)canonicalID {
330
- return [ NSString stringWithFormat: @" %s IS NaN " , _field. CanonicalString (). c_str ()] ;
249
+ return util::MakeNSString (_filter. CanonicalId ()) ;
331
250
}
332
251
333
252
- (const firebase::firestore::model::FieldPath &)field {
334
- return _field ;
253
+ return _filter. field () ;
335
254
}
336
255
337
256
- (NSString *)description {
338
- return [ self canonicalID ] ;
257
+ return util::MakeNSString (_filter. ToString ()) ;
339
258
}
340
259
341
260
- (BOOL )isEqual : (id )other {
342
261
if (other == self) return YES ;
343
262
if (![[other class ] isEqual: [self class ]]) return NO ;
344
263
345
- return _field == ((FSTNanFilter *)other)->_field ;
264
+ return _filter == ((FSTNanFilter *)other)->_filter ;
346
265
}
347
266
348
267
- (NSUInteger )hash {
349
- return util:: Hash (_field );
268
+ return _filter. Hash ();
350
269
}
351
270
@end
352
271
0 commit comments