diff options
author | Michael Lehenbauer <mikelehen@gmail.com> | 2018-04-17 15:07:25 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-17 15:07:25 -0700 |
commit | f2ec9e11fba82d4a76d989293d270a37ad1373a2 (patch) | |
tree | 48df0f0900c8e379557d9e43e385c4fde9f2b90b /Firestore/Source/Remote | |
parent | 9329e6e09bed6925b3292aa05fea28e2bcd4d9ef (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.mm | 89 |
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 { |