Skip to content

Commit 64d8a40

Browse files
authored
Migrate FSTReferenceValue to FSTDelegateValue (#3177)
* Add FieldValue::Reference * Migrate FSTReferenceValue to FSTDelegateValue * Build Objective-C components with CMake Build only the things required for FSTFieldValue
1 parent de7eb4f commit 64d8a40

File tree

13 files changed

+81
-126
lines changed

13 files changed

+81
-126
lines changed

Firestore/Example/Tests/API/FSTUserDataConverterTests.mm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,9 @@ - (void)testConvertsResourceNames {
144144
];
145145
for (FSTDocumentKeyReference *value in values) {
146146
FSTFieldValue *wrapped = FSTTestFieldValue(value);
147-
XCTAssertEqualObjects([wrapped class], [FSTReferenceValue class]);
147+
XCTAssertEqualObjects([wrapped class], [FSTDelegateValue class]);
148148
XCTAssertEqualObjects([wrapped value], [FSTDocumentKey keyWithDocumentKey:value.key]);
149-
XCTAssertTrue(((FSTReferenceValue *)wrapped).databaseID == value.databaseID);
149+
XCTAssertTrue(((FSTDelegateValue *)wrapped).referenceValue.database_id() == value.databaseID);
150150
XCTAssertEqual(wrapped.type, FieldValue::Type::Reference);
151151
}
152152
}

Firestore/Example/Tests/Model/FSTFieldValueTests.mm

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,7 @@
6060
} else if ([value isKindOfClass:[FSTDocumentKeyReference class]]) {
6161
// We directly convert these here so that the databaseIDs can be different.
6262
FSTDocumentKeyReference *reference = (FSTDocumentKeyReference *)value;
63-
wrappedValue =
64-
[FSTReferenceValue referenceValue:[FSTDocumentKey keyWithDocumentKey:reference.key]
65-
databaseID:reference.databaseID];
63+
wrappedValue = FieldValue::FromReference(reference.databaseID, reference.key).Wrap();
6664
} else {
6765
wrappedValue = FSTTestFieldValue(value);
6866
}
@@ -317,9 +315,7 @@ - (void)testValueEquality {
317315
@[ FSTTestFieldValue(FSTTestGeoPoint(0, 1)), FieldValue::FromGeoPoint(GeoPoint(0, 1)).Wrap() ],
318316
@[ FSTTestFieldValue(FSTTestGeoPoint(1, 0)) ],
319317
@[
320-
[FSTReferenceValue
321-
referenceValue:[FSTDocumentKey keyWithDocumentKey:FSTTestDocKey(@"coll/doc1")]
322-
databaseID:database_id],
318+
FieldValue::FromReference(database_id, FSTTestDocKey(@"coll/doc1")).Wrap(),
323319
FSTTestFieldValue(FSTTestRef("project", DatabaseId::kDefault, @"coll/doc1"))
324320
],
325321
@[ FSTTestRef("project", "(default)", @"coll/doc2") ],

Firestore/Source/API/FIRDocumentSnapshot.mm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,8 @@ - (id)convertedValue:(FSTFieldValue *)value options:(const FieldValueOptions &)o
193193
} else if (value.type == FieldValue::Type::Array) {
194194
return [self convertedArray:(FSTArrayValue *)value options:options];
195195
} else if (value.type == FieldValue::Type::Reference) {
196-
FSTReferenceValue *ref = (FSTReferenceValue *)value;
197-
const DatabaseId &refDatabase = ref.databaseID;
196+
const auto &ref = ((FSTDelegateValue *)value).referenceValue;
197+
const DatabaseId &refDatabase = ref.database_id();
198198
const DatabaseId &database = _snapshot.firestore()->database_id();
199199
if (refDatabase != database) {
200200
// TODO(b/32073923): Log this as a proper warning.
@@ -205,7 +205,7 @@ - (id)convertedValue:(FSTFieldValue *)value options:(const FieldValueOptions &)o
205205
refDatabase.database_id().c_str(), database.project_id().c_str(),
206206
database.database_id().c_str());
207207
}
208-
DocumentKey key = [[ref valueWithOptions:options] key];
208+
const DocumentKey &key = ref.key();
209209
return [[FIRDocumentReference alloc] initWithKey:key firestore:_snapshot.firestore()];
210210
} else {
211211
return [value valueWithOptions:options];

Firestore/Source/API/FIRQuery.mm

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -467,9 +467,8 @@ - (FSTBound *)boundFromSnapshot:(FIRDocumentSnapshot *)snapshot isBefore:(BOOL)i
467467
// orders), multiple documents could match the position, yielding duplicate results.
468468
for (FSTSortOrder *sortOrder in self.query.sortOrders) {
469469
if (sortOrder.field == FieldPath::KeyFieldPath()) {
470-
[components addObject:[FSTReferenceValue
471-
referenceValue:[FSTDocumentKey keyWithDocumentKey:document.key]
472-
databaseID:self.firestore.databaseID]];
470+
[components
471+
addObject:FieldValue::FromReference(self.firestore.databaseID, document.key).Wrap()];
473472
} else {
474473
FSTFieldValue *value = [document fieldForPath:sortOrder.field];
475474

@@ -524,8 +523,7 @@ - (FSTBound *)boundFromFieldValues:(NSArray<id> *)fieldValues isBefore:(BOOL)isB
524523
path.CanonicalString());
525524
}
526525
DocumentKey key{path};
527-
fieldValue = [FSTReferenceValue referenceValue:[FSTDocumentKey keyWithDocumentKey:key]
528-
databaseID:self.firestore.databaseID];
526+
fieldValue = FieldValue::FromReference(self.firestore.databaseID, key).Wrap();
529527
}
530528

531529
[components addObject:fieldValue];

Firestore/Source/API/FSTUserDataConverter.mm

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,8 +476,7 @@ - (nullable FSTFieldValue *)parseScalarValue:(nullable id)input context:(ParseCo
476476
other.project_id(), other.database_id(), _databaseID.project_id(),
477477
_databaseID.database_id(), context.FieldDescription());
478478
}
479-
return [FSTReferenceValue referenceValue:[FSTDocumentKey keyWithDocumentKey:reference.key]
480-
databaseID:_databaseID];
479+
return FieldValue::FromReference(_databaseID, reference.key).Wrap();
481480

482481
} else {
483482
ThrowInvalidArgument("Unsupported type: %s%s", NSStringFromClass([input class]),

Firestore/Source/Core/FSTQuery.mm

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,11 @@ - (BOOL)isEqual:(id)other {
187187
- (BOOL)matchesDocument:(FSTDocument *)document {
188188
if (_field.IsKeyFieldPath()) {
189189
HARD_ASSERT(self.value.type == FieldValue::Type::Reference,
190-
"Comparing on key, but filter value not a FSTReferenceValue.");
190+
"Comparing on key, but filter value not a Reference.");
191191
HARD_ASSERT(self.filterOperator != Filter::Operator::ArrayContains,
192192
"arrayContains queries don't make sense on document keys.");
193-
FSTReferenceValue *refValue = (FSTReferenceValue *)self.value;
194-
NSComparisonResult comparison = util::WrapCompare(document.key, refValue.value.key);
193+
const auto &ref = ((FSTDelegateValue *)self.value).referenceValue;
194+
NSComparisonResult comparison = util::WrapCompare(document.key, ref.key());
195195
return [self matchesComparison:comparison];
196196
} else {
197197
return [self matchesValue:[document fieldForPath:self.field]];
@@ -477,8 +477,8 @@ - (BOOL)sortsBeforeDocument:(FSTDocument *)document
477477
if (sortOrderComponent.field == FieldPath::KeyFieldPath()) {
478478
HARD_ASSERT(fieldValue.type == FieldValue::Type::Reference,
479479
"FSTBound has a non-key value where the key path is being used %s", fieldValue);
480-
FSTReferenceValue *refValue = (FSTReferenceValue *)fieldValue;
481-
comparison = util::Compare(refValue.value.key, document.key);
480+
const auto &ref = ((FSTDelegateValue *)fieldValue).referenceValue;
481+
comparison = util::Compare(ref.key(), document.key);
482482
} else {
483483
FSTFieldValue *docValue = [document fieldForPath:sortOrderComponent.field];
484484
HARD_ASSERT(docValue != nil,

Firestore/Source/Model/FSTFieldValue.h

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,6 @@ typedef NS_ENUM(NSInteger, FSTTypeOrder) {
103103

104104
@end
105105

106-
/**
107-
* A reference value stored in Firestore.
108-
*/
109-
@interface FSTReferenceValue : FSTFieldValue <FSTDocumentKey *>
110-
111-
+ (instancetype)referenceValue:(FSTDocumentKey *)value databaseID:(model::DatabaseId)databaseID;
112-
113-
@property(nonatomic, assign, readonly) const model::DatabaseId &databaseID;
114-
115-
@end
116-
117106
/**
118107
* A structured object value stored in Firestore.
119108
*/
@@ -190,6 +179,8 @@ typedef NS_ENUM(NSInteger, FSTTypeOrder) {
190179
@interface FSTDelegateValue : FSTFieldValue <id>
191180
+ (instancetype)delegateWithValue:(model::FieldValue &&)value;
192181
- (const model::FieldValue &)internalValue;
182+
183+
- (const model::FieldValue::Reference &)referenceValue;
193184
@end
194185

195186
NS_ASSUME_NONNULL_END

Firestore/Source/Model/FSTFieldValue.mm

Lines changed: 5 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -128,76 +128,6 @@ - (double)doubleValue {
128128

129129
@end
130130

131-
#pragma mark - FSTReferenceValue
132-
133-
@interface FSTReferenceValue ()
134-
@property(nonatomic, strong, readonly) FSTDocumentKey *key;
135-
@end
136-
137-
@implementation FSTReferenceValue {
138-
DatabaseId _databaseID;
139-
}
140-
141-
+ (instancetype)referenceValue:(FSTDocumentKey *)value databaseID:(DatabaseId)databaseID {
142-
return [[FSTReferenceValue alloc] initWithValue:value databaseID:std::move(databaseID)];
143-
}
144-
145-
- (id)initWithValue:(FSTDocumentKey *)value databaseID:(DatabaseId)databaseID {
146-
self = [super init];
147-
if (self) {
148-
_key = value;
149-
_databaseID = std::move(databaseID);
150-
}
151-
return self;
152-
}
153-
154-
- (id)value {
155-
return self.key;
156-
}
157-
158-
- (FieldValue::Type)type {
159-
return FieldValue::Type::Reference;
160-
}
161-
162-
- (FSTTypeOrder)typeOrder {
163-
return FSTTypeOrderReference;
164-
}
165-
166-
- (BOOL)isEqual:(id)other {
167-
if (other == self) {
168-
return YES;
169-
}
170-
if (!([other isKindOfClass:[FSTFieldValue class]] &&
171-
((FSTFieldValue *)other).type == FieldValue::Type::Reference)) {
172-
return NO;
173-
}
174-
175-
FSTReferenceValue *otherRef = (FSTReferenceValue *)other;
176-
return self.key.key == otherRef.key.key && self.databaseID == otherRef.databaseID;
177-
}
178-
179-
- (NSUInteger)hash {
180-
NSUInteger result = self.databaseID.Hash();
181-
result = 31 * result + [self.key hash];
182-
return result;
183-
}
184-
185-
- (NSComparisonResult)compare:(FSTFieldValue *)other {
186-
if (other.type == FieldValue::Type::Reference) {
187-
FSTReferenceValue *ref = (FSTReferenceValue *)other;
188-
NSComparisonResult cmp = WrapCompare(self.databaseID.project_id(), ref.databaseID.project_id());
189-
if (cmp != NSOrderedSame) {
190-
return cmp;
191-
}
192-
cmp = WrapCompare(self.databaseID.database_id(), ref.databaseID.database_id());
193-
return cmp != NSOrderedSame ? cmp : WrapCompare(self.key.key, ref.key.key);
194-
} else {
195-
return [self defaultCompare:other];
196-
}
197-
}
198-
199-
@end
200-
201131
#pragma mark - FSTObjectValue
202132

203133
/**
@@ -480,6 +410,10 @@ + (instancetype)delegateWithValue:(FieldValue &&)value {
480410
return _internalValue;
481411
}
482412

413+
- (const FieldValue::Reference &)referenceValue {
414+
return _internalValue.reference_value();
415+
}
416+
483417
- (id)initWithValue:(FieldValue &&)value {
484418
self = [super init];
485419
if (self) {
@@ -560,7 +494,7 @@ - (id)value {
560494
case FieldValue::Type::Blob:
561495
return MakeNSData(self.internalValue.blob_value());
562496
case FieldValue::Type::Reference:
563-
HARD_FAIL("TODO(rsgowman): implement");
497+
return [FSTDocumentKey keyWithDocumentKey:self.referenceValue.key()];
564498
case FieldValue::Type::GeoPoint:
565499
return MakeFIRGeoPoint(self.internalValue.geo_point_value());
566500
case FieldValue::Type::Array:

Firestore/Source/Remote/FSTSerializerBeta.mm

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,8 @@ - (GCFSValue *)encodedFieldValue:(FSTFieldValue *)fieldValue {
222222
case FieldValue::Type::Blob:
223223
return [self encodedBlobValue:[fieldValue value]];
224224
case FieldValue::Type::Reference: {
225-
FSTReferenceValue *ref = (FSTReferenceValue *)fieldValue;
226-
DocumentKey key = [[ref value] key];
227-
return [self encodedReferenceValueForDatabaseID:[ref databaseID] key:key];
225+
const auto &ref = ((FSTDelegateValue *)fieldValue).referenceValue;
226+
return [self encodedReferenceValueForDatabaseID:ref.database_id() key:ref.key()];
228227
}
229228
case FieldValue::Type::GeoPoint:
230229
return [self encodedGeoPointValue:[fieldValue value]];
@@ -345,7 +344,7 @@ - (GCFSValue *)encodedReferenceValueForDatabaseID:(const DatabaseId &)databaseID
345344
return result;
346345
}
347346

348-
- (FSTReferenceValue *)decodedReferenceValue:(NSString *)resourceName {
347+
- (FSTFieldValue *)decodedReferenceValue:(NSString *)resourceName {
349348
const ResourcePath path = [self decodedResourcePathWithDatabaseID:resourceName];
350349
const std::string &project = path[1];
351350
const std::string &database = path[3];
@@ -355,8 +354,7 @@ - (FSTReferenceValue *)decodedReferenceValue:(NSString *)resourceName {
355354
HARD_ASSERT(database_id == _databaseID, "Database %s:%s cannot encode reference from %s:%s",
356355
_databaseID.project_id(), _databaseID.database_id(), database_id.project_id(),
357356
database_id.database_id());
358-
return [FSTReferenceValue referenceValue:[FSTDocumentKey keyWithDocumentKey:key]
359-
databaseID:_databaseID];
357+
return FieldValue::FromReference(_databaseID, key).Wrap();
360358
}
361359

362360
- (GCFSArrayValue *)encodedArrayValue:(FSTArrayValue *)arrayValue {

Firestore/core/src/firebase/firestore/api/query_core.mm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,9 @@ QuerySnapshot result(firestore_, query_, std::move(snapshot),
215215
"is not because it has an odd number of segments.",
216216
path.CanonicalString());
217217
}
218-
field_value = [FSTReferenceValue
219-
referenceValue:[FSTDocumentKey keyWithDocumentKey:DocumentKey{path}]
220-
databaseID:firestore_->database_id()];
218+
field_value = FieldValue::FromReference(firestore_->database_id(),
219+
DocumentKey{path})
220+
.Wrap();
221221
} else if (field_value.type != FieldValue::Type::Reference) {
222222
ThrowInvalidArgument(
223223
"Invalid query. When querying by document ID you must provide a "

0 commit comments

Comments
 (0)