aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/Source/Remote
diff options
context:
space:
mode:
authorGravatar Michael Lehenbauer <mikelehen@gmail.com>2018-04-17 15:07:25 -0700
committerGravatar GitHub <noreply@github.com>2018-04-17 15:07:25 -0700
commitf2ec9e11fba82d4a76d989293d270a37ad1373a2 (patch)
tree48df0f0900c8e379557d9e43e385c4fde9f2b90b /Firestore/Source/Remote
parent9329e6e09bed6925b3292aa05fea28e2bcd4d9ef (diff)
Serialize array transform mutations. (#1107)
* Serialize array transform mutations. * Improve ArrayTransform constructor to avoid extra copying.
Diffstat (limited to 'Firestore/Source/Remote')
-rw-r--r--Firestore/Source/Remote/FSTSerializerBeta.mm89
1 files changed, 78 insertions, 11 deletions
diff --git a/Firestore/Source/Remote/FSTSerializerBeta.mm b/Firestore/Source/Remote/FSTSerializerBeta.mm
index c8b0fa4..ebb49a7 100644
--- a/Firestore/Source/Remote/FSTSerializerBeta.mm
+++ b/Firestore/Source/Remote/FSTSerializerBeta.mm
@@ -57,6 +57,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;
@@ -572,31 +573,97 @@ NS_ASSUME_NONNULL_BEGIN
(const std::vector<FieldTransform> &)fieldTransforms {
NSMutableArray *protos = [NSMutableArray array];
for (const FieldTransform &fieldTransform : fieldTransforms) {
- FSTAssert(fieldTransform.transformation().type() == TransformOperation::Type::ServerTimestamp,
- @"Unknown transform: %d type", fieldTransform.transformation().type());
- GCFSDocumentTransform_FieldTransform *proto = [GCFSDocumentTransform_FieldTransform message];
- proto.fieldPath = util::WrapNSString(fieldTransform.path().CanonicalString());
- proto.setToServerValue = GCFSDocumentTransform_FieldTransform_ServerValue_RequestTime;
+ GCFSDocumentTransform_FieldTransform *proto = [self encodedFieldTransform:fieldTransform];
[protos addObject:proto];
}
return protos;
}
+- (GCFSDocumentTransform_FieldTransform *)encodedFieldTransform:
+ (const FieldTransform &)fieldTransform {
+ GCFSDocumentTransform_FieldTransform *proto = [GCFSDocumentTransform_FieldTransform message];
+ proto.fieldPath = util::WrapNSString(fieldTransform.path().CanonicalString());
+ if (fieldTransform.transformation().type() == TransformOperation::Type::ServerTimestamp) {
+ proto.setToServerValue = GCFSDocumentTransform_FieldTransform_ServerValue_RequestTime;
+
+ } else if (fieldTransform.transformation().type() == TransformOperation::Type::ArrayUnion) {
+ proto.appendMissingElements = [self
+ encodedArrayTransformElements:ArrayTransform::Elements(fieldTransform.transformation())];
+
+ } else if (fieldTransform.transformation().type() == TransformOperation::Type::ArrayRemove) {
+ proto.removeAllFromArray_p = [self
+ encodedArrayTransformElements:ArrayTransform::Elements(fieldTransform.transformation())];
+
+ } else {
+ FSTFail(@"Unknown transform: %d type", fieldTransform.transformation().type());
+ }
+ return proto;
+}
+
+- (GCFSArrayValue *)encodedArrayTransformElements:(const std::vector<FSTFieldValue *> &)elements {
+ GCFSArrayValue *proto = [GCFSArrayValue message];
+ NSMutableArray<GCFSValue *> *protoContents = [proto valuesArray];
+
+ for (FSTFieldValue *element : elements) {
+ GCFSValue *converted = [self encodedFieldValue:element];
+ [protoContents addObject:converted];
+ }
+ return proto;
+}
+
- (std::vector<FieldTransform>)decodedFieldTransforms:
(NSArray<GCFSDocumentTransform_FieldTransform *> *)protos {
std::vector<FieldTransform> fieldTransforms;
fieldTransforms.reserve(protos.count);
+
for (GCFSDocumentTransform_FieldTransform *proto in protos) {
- FSTAssert(
- proto.setToServerValue == GCFSDocumentTransform_FieldTransform_ServerValue_RequestTime,
- @"Unknown transform setToServerValue: %d", proto.setToServerValue);
- fieldTransforms.emplace_back(
- FieldPath::FromServerFormat(util::MakeStringView(proto.fieldPath)),
- absl::make_unique<ServerTimestampTransform>(ServerTimestampTransform::Get()));
+ switch (proto.transformTypeOneOfCase) {
+ case GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase_SetToServerValue: {
+ FSTAssert(
+ proto.setToServerValue == GCFSDocumentTransform_FieldTransform_ServerValue_RequestTime,
+ @"Unknown transform setToServerValue: %d", proto.setToServerValue);
+ fieldTransforms.emplace_back(
+ FieldPath::FromServerFormat(util::MakeStringView(proto.fieldPath)),
+ absl::make_unique<ServerTimestampTransform>(ServerTimestampTransform::Get()));
+ break;
+ }
+
+ case GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase_AppendMissingElements: {
+ std::vector<FSTFieldValue *> elements =
+ [self decodedArrayTransformElements:proto.appendMissingElements];
+ fieldTransforms.emplace_back(
+ FieldPath::FromServerFormat(util::MakeStringView(proto.fieldPath)),
+ absl::make_unique<ArrayTransform>(TransformOperation::Type::ArrayUnion,
+ std::move(elements)));
+ break;
+ }
+
+ case GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase_RemoveAllFromArray_p: {
+ std::vector<FSTFieldValue *> elements =
+ [self decodedArrayTransformElements:proto.removeAllFromArray_p];
+ fieldTransforms.emplace_back(
+ FieldPath::FromServerFormat(util::MakeStringView(proto.fieldPath)),
+ absl::make_unique<ArrayTransform>(TransformOperation::Type::ArrayRemove,
+ std::move(elements)));
+ break;
+ }
+
+ default:
+ FSTFail(@"Unknown transform: %@", proto);
+ }
}
+
return fieldTransforms;
}
+- (std::vector<FSTFieldValue *>)decodedArrayTransformElements:(GCFSArrayValue *)proto {
+ __block std::vector<FSTFieldValue *> elements;
+ [proto.valuesArray enumerateObjectsUsingBlock:^(GCFSValue *value, NSUInteger idx, BOOL *stop) {
+ elements.push_back([self decodedFieldValue:value]);
+ }];
+ return elements;
+}
+
#pragma mark - FSTMutationResult <= GCFSWriteResult proto
- (FSTMutationResult *)decodedMutationResult:(GCFSWriteResult *)mutation {