aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/Source/API/FSTUserDataConverter.mm
diff options
context:
space:
mode:
Diffstat (limited to 'Firestore/Source/API/FSTUserDataConverter.mm')
-rw-r--r--Firestore/Source/API/FSTUserDataConverter.mm45
1 files changed, 42 insertions, 3 deletions
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