diff options
Diffstat (limited to 'Firestore/Source/API')
-rw-r--r-- | Firestore/Source/API/FIRFieldValue+Internal.h | 12 | ||||
-rw-r--r-- | Firestore/Source/API/FIRFieldValue.mm | 38 | ||||
-rw-r--r-- | Firestore/Source/API/FSTUserDataConverter.mm | 45 |
3 files changed, 92 insertions, 3 deletions
diff --git a/Firestore/Source/API/FIRFieldValue+Internal.h b/Firestore/Source/API/FIRFieldValue+Internal.h index 2eb927e..1618cd4 100644 --- a/Firestore/Source/API/FIRFieldValue+Internal.h +++ b/Firestore/Source/API/FIRFieldValue+Internal.h @@ -42,4 +42,16 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; @end +/** FIRFieldValue class for array unions. */ +@interface FSTArrayUnionFieldValue : FIRFieldValue +- (instancetype)init NS_UNAVAILABLE; +@property(strong, nonatomic, readonly) NSArray<id> *elements; +@end + +/** FIRFieldValue class for array removes. */ +@interface FSTArrayRemoveFieldValue : FIRFieldValue +- (instancetype)init NS_UNAVAILABLE; +@property(strong, nonatomic, readonly) NSArray<id> *elements; +@end + NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/API/FIRFieldValue.mm b/Firestore/Source/API/FIRFieldValue.mm index 0d0a9c4..e0ed8c7 100644 --- a/Firestore/Source/API/FIRFieldValue.mm +++ b/Firestore/Source/API/FIRFieldValue.mm @@ -82,6 +82,36 @@ NS_ASSUME_NONNULL_BEGIN @end +#pragma mark - FSTArrayUnionFieldValue + +@interface FSTArrayUnionFieldValue () +- (instancetype)initWithElements:(NSArray<id> *)elements; +@end + +@implementation FSTArrayUnionFieldValue +- (instancetype)initWithElements:(NSArray<id> *)elements { + if (self = [super initPrivate]) { + _elements = elements; + } + return self; +} +@end + +#pragma mark - FSTArrayRemoveFieldValue + +@interface FSTArrayRemoveFieldValue () +- (instancetype)initWithElements:(NSArray<id> *)elements; +@end + +@implementation FSTArrayRemoveFieldValue +- (instancetype)initWithElements:(NSArray<id> *)elements { + if (self = [super initPrivate]) { + _elements = elements; + } + return self; +} +@end + #pragma mark - FIRFieldValue @implementation FIRFieldValue @@ -99,6 +129,14 @@ NS_ASSUME_NONNULL_BEGIN return [FSTServerTimestampFieldValue serverTimestampFieldValue]; } ++ (instancetype)fieldValueForArrayUnion:(NSArray<id> *)elements { + return [[FSTArrayUnionFieldValue alloc] initWithElements:elements]; +} + ++ (instancetype)fieldValueForArrayRemove:(NSArray<id> *)elements { + return [[FSTArrayRemoveFieldValue alloc] initWithElements:elements]; +} + @end NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/API/FSTUserDataConverter.mm b/Firestore/Source/API/FSTUserDataConverter.mm index dff9235..90d68d8 100644 --- a/Firestore/Source/API/FSTUserDataConverter.mm +++ b/Firestore/Source/API/FSTUserDataConverter.mm @@ -44,6 +44,7 @@ #include "absl/memory/memory.h" namespace util = firebase::firestore::util; +using firebase::firestore::model::ArrayTransform; using firebase::firestore::model::DatabaseId; using firebase::firestore::model::DocumentKey; using firebase::firestore::model::FieldMask; @@ -165,7 +166,11 @@ typedef NS_ENUM(NSInteger, FSTUserDataSource) { FSTUserDataSourceSet, FSTUserDataSourceMergeSet, FSTUserDataSourceUpdate, - FSTUserDataSourceQueryValue, // from a where clause or cursor bound. + /** + * Indicates the source is a where clause, cursor bound, arrayUnion() element, etc. In particular, + * this will result in [FSTParseContext isWrite] returning NO. + */ + FSTUserDataSourceArgument, }; #pragma mark - FSTParseContext @@ -318,7 +323,7 @@ typedef NS_ENUM(NSInteger, FSTUserDataSource) { case FSTUserDataSourceMergeSet: // Falls through. case FSTUserDataSourceUpdate: return YES; - case FSTUserDataSourceQueryValue: + case FSTUserDataSourceArgument: return NO; default: FSTThrowInvalidArgument(@"Unexpected case for FSTUserDataSource: %d", self.dataSource); @@ -489,7 +494,7 @@ typedef NS_ENUM(NSInteger, FSTUserDataSource) { - (FSTFieldValue *)parsedQueryValue:(id)input { FSTParseContext *context = - [FSTParseContext contextWithSource:FSTUserDataSourceQueryValue + [FSTParseContext contextWithSource:FSTUserDataSourceArgument path:absl::make_unique<FieldPath>(FieldPath::EmptyPath())]; FSTFieldValue *_Nullable parsed = [self parseData:input context:context]; FSTAssert(parsed, @"Parsed data should not be nil."); @@ -593,10 +598,28 @@ typedef NS_ENUM(NSInteger, FSTUserDataSource) { @"SetOptions.merge()%@", [context fieldDescription]); } + } else if ([fieldValue isKindOfClass:[FSTServerTimestampFieldValue class]]) { [context appendToFieldTransformsWithFieldPath:*context.path transformOperation:absl::make_unique<ServerTimestampTransform>( ServerTimestampTransform::Get())]; + + } else if ([fieldValue isKindOfClass:[FSTArrayUnionFieldValue class]]) { + std::vector<FSTFieldValue *> parsedElements = + [self parseArrayTransformElements:((FSTArrayUnionFieldValue *)fieldValue).elements]; + auto array_union = + absl::make_unique<ArrayTransform>(TransformOperation::Type::ArrayUnion, parsedElements); + [context appendToFieldTransformsWithFieldPath:*context.path + transformOperation:std::move(array_union)]; + + } else if ([fieldValue isKindOfClass:[FSTArrayRemoveFieldValue class]]) { + std::vector<FSTFieldValue *> parsedElements = + [self parseArrayTransformElements:((FSTArrayRemoveFieldValue *)fieldValue).elements]; + auto array_remove = + absl::make_unique<ArrayTransform>(TransformOperation::Type::ArrayRemove, parsedElements); + [context appendToFieldTransformsWithFieldPath:*context.path + transformOperation:std::move(array_remove)]; + } else { FSTFail(@"Unknown FIRFieldValue type: %@", NSStringFromClass([fieldValue class])); } @@ -753,6 +776,22 @@ typedef NS_ENUM(NSInteger, FSTUserDataSource) { } } +- (std::vector<FSTFieldValue *>)parseArrayTransformElements:(NSArray<id> *)elements { + std::vector<FSTFieldValue *> results; + for (id element in elements) { + // Although array transforms are used with writes, the actual elements being unioned or removed + // are not considered writes since they cannot contain any FieldValue sentinels, etc. + FSTParseContext *context = + [FSTParseContext contextWithSource:FSTUserDataSourceArgument + path:absl::make_unique<FieldPath>(FieldPath::EmptyPath())]; + FSTFieldValue *parsedElement = [self parseData:element context:context]; + FSTAssert(parsedElement && context.fieldTransforms->size() == 0, + @"Failed to properly parse array transform element: %@", element); + results.push_back(parsedElement); + } + return results; +} + @end NS_ASSUME_NONNULL_END |