From 2ac778f312301a8dd10c3c6498a59ce536abd738 Mon Sep 17 00:00:00 2001 From: zxu Date: Tue, 10 Apr 2018 16:28:22 -0400 Subject: Port FieldTransform to C++ (#1033) * port FieldMask to C++ * address changes * address changes * fix test * address change * Port transform operations (FSTTransformOperation, FSTServerTimestampTransform) to C++ * address changes * address changes * address changes * implement `FieldTransform` in C++ * port `FieldTransform` * make `fieldTransforms` shared inside `context` * address changes * fix lint * address changes --- Firestore/Source/Model/FSTMutation.h | 22 ++------- Firestore/Source/Model/FSTMutation.mm | 93 +++++++++++++---------------------- 2 files changed, 40 insertions(+), 75 deletions(-) (limited to 'Firestore/Source/Model') diff --git a/Firestore/Source/Model/FSTMutation.h b/Firestore/Source/Model/FSTMutation.h index 2fa8806..38c35bf 100644 --- a/Firestore/Source/Model/FSTMutation.h +++ b/Firestore/Source/Model/FSTMutation.h @@ -22,6 +22,7 @@ #include "Firestore/core/src/firebase/firestore/model/document_key.h" #include "Firestore/core/src/firebase/firestore/model/field_mask.h" #include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/field_transform.h" #include "Firestore/core/src/firebase/firestore/model/transform_operations.h" @class FSTDocument; @@ -33,19 +34,6 @@ NS_ASSUME_NONNULL_BEGIN -#pragma mark - FSTFieldTransform - -/** A field path and the TransformOperation to perform upon it. */ -@interface FSTFieldTransform : NSObject -- (instancetype)init NS_UNAVAILABLE; -- (instancetype)initWithPath:(firebase::firestore::model::FieldPath)path - transform: - (std::unique_ptr)transform - NS_DESIGNATED_INITIALIZER; -- (const firebase::firestore::model::FieldPath &)path; -- (const firebase::firestore::model::TransformOperation *)transform; -@end - #pragma mark - FSTPrecondition typedef NS_ENUM(NSUInteger, FSTPreconditionExists) { @@ -103,7 +91,7 @@ typedef NS_ENUM(NSUInteger, FSTPreconditionExists) { /** * The resulting fields returned from the backend after a FSTTransformMutation has been committed. - * Contains one FieldValue for each FSTFieldTransform that was in the mutation. + * Contains one FieldValue for each FieldTransform that was in the mutation. * * Will be nil if the mutation was not a FSTTransformMutation. */ @@ -284,14 +272,14 @@ typedef NS_ENUM(NSUInteger, FSTPreconditionExists) { * Initializes a new transform mutation with the specified field transforms. * * @param key Identifies the location of the document to mutate. - * @param fieldTransforms A list of FSTFieldTransform objects to perform to the document. + * @param fieldTransforms A list of FieldTransform objects to perform to the document. */ - (instancetype)initWithKey:(firebase::firestore::model::DocumentKey)key - fieldTransforms:(NSArray *)fieldTransforms + fieldTransforms:(std::vector)fieldTransforms NS_DESIGNATED_INITIALIZER; /** The field transforms to use when transforming the document. */ -@property(nonatomic, strong, readonly) NSArray *fieldTransforms; +- (const std::vector &)fieldTransforms; @end diff --git a/Firestore/Source/Model/FSTMutation.mm b/Firestore/Source/Model/FSTMutation.mm index a18053c..dd649a0 100644 --- a/Firestore/Source/Model/FSTMutation.mm +++ b/Firestore/Source/Model/FSTMutation.mm @@ -17,7 +17,9 @@ #import "Firestore/Source/Model/FSTMutation.h" #include +#include #include +#include #import "FIRTimestamp.h" @@ -30,56 +32,18 @@ #include "Firestore/core/src/firebase/firestore/model/document_key.h" #include "Firestore/core/src/firebase/firestore/model/field_mask.h" #include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/field_transform.h" #include "Firestore/core/src/firebase/firestore/model/transform_operations.h" using firebase::firestore::model::DocumentKey; using firebase::firestore::model::FieldMask; using firebase::firestore::model::FieldPath; +using firebase::firestore::model::FieldTransform; using firebase::firestore::model::ServerTimestampTransform; using firebase::firestore::model::TransformOperation; NS_ASSUME_NONNULL_BEGIN -#pragma mark - FSTFieldTransform - -@implementation FSTFieldTransform { - FieldPath _path; - std::unique_ptr _transform; -} - -- (instancetype)initWithPath:(FieldPath)path - transform:(std::unique_ptr)transform { - self = [super init]; - if (self) { - _path = std::move(path); - _transform = std::move(transform); - } - return self; -} - -- (BOOL)isEqual:(id)other { - if (other == self) return YES; - if (![[other class] isEqual:[self class]]) return NO; - FSTFieldTransform *otherFieldTransform = other; - return self.path == otherFieldTransform.path && *self.transform == *otherFieldTransform.transform; -} - -- (NSUInteger)hash { - NSUInteger hash = self.path.Hash(); - hash = hash * 31 + self.transform->Hash(); - return hash; -} - -- (const firebase::firestore::model::FieldPath &)path { - return _path; -} - -- (const firebase::firestore::model::TransformOperation *)transform { - return _transform.get(); -} - -@end - #pragma mark - FSTPrecondition @implementation FSTPrecondition @@ -399,20 +363,27 @@ NS_ASSUME_NONNULL_BEGIN @end -@implementation FSTTransformMutation +@implementation FSTTransformMutation { + /** The field transforms to use when transforming the document. */ + std::vector _fieldTransforms; +} - (instancetype)initWithKey:(DocumentKey)key - fieldTransforms:(NSArray *)fieldTransforms { + fieldTransforms:(std::vector)fieldTransforms { // NOTE: We set a precondition of exists: true as a safety-check, since we always combine // FSTTransformMutations with a FSTSetMutation or FSTPatchMutation which (if successful) should // end up with an existing document. if (self = [super initWithKey:std::move(key) precondition:[FSTPrecondition preconditionWithExists:YES]]) { - _fieldTransforms = fieldTransforms; + _fieldTransforms = std::move(fieldTransforms); } return self; } +- (const std::vector &)fieldTransforms { + return _fieldTransforms; +} + - (BOOL)isEqual:(id)other { if (other == self) { return YES; @@ -423,20 +394,26 @@ NS_ASSUME_NONNULL_BEGIN FSTTransformMutation *otherMutation = (FSTTransformMutation *)other; return [self.key isEqual:otherMutation.key] && - [self.fieldTransforms isEqual:otherMutation.fieldTransforms] && + self.fieldTransforms == otherMutation.fieldTransforms && [self.precondition isEqual:otherMutation.precondition]; } - (NSUInteger)hash { NSUInteger result = [self.key hash]; result = 31 * result + [self.precondition hash]; - result = 31 * result + [self.fieldTransforms hash]; + for (const auto &transform : self.fieldTransforms) { + result = 31 * result + transform.Hash(); + } return result; } - (NSString *)description { - return [NSString stringWithFormat:@"", - self.key.ToString().c_str(), self.fieldTransforms, + std::string fieldTransforms; + for (const auto &transform : self.fieldTransforms) { + fieldTransforms += " " + transform.path().CanonicalString(); + } + return [NSString stringWithFormat:@"", + self.key.ToString().c_str(), fieldTransforms.c_str(), self.precondition]; } @@ -486,19 +463,19 @@ NS_ASSUME_NONNULL_BEGIN (FSTMaybeDocument *_Nullable)baseDocument writeTime:(FIRTimestamp *)localWriteTime { NSMutableArray *transformResults = [NSMutableArray array]; - for (FSTFieldTransform *fieldTransform in self.fieldTransforms) { - if (fieldTransform.transform->type() == TransformOperation::Type::ServerTimestamp) { + for (const FieldTransform &fieldTransform : self.fieldTransforms) { + if (fieldTransform.transformation().type() == TransformOperation::Type::ServerTimestamp) { FSTFieldValue *previousValue = nil; if ([baseDocument isMemberOfClass:[FSTDocument class]]) { - previousValue = [((FSTDocument *)baseDocument) fieldForPath:fieldTransform.path]; + previousValue = [((FSTDocument *)baseDocument) fieldForPath:fieldTransform.path()]; } [transformResults addObject:[FSTServerTimestampValue serverTimestampValueWithLocalWriteTime:localWriteTime previousValue:previousValue]]; } else { - FSTFail(@"Encountered unknown transform: %@", fieldTransform); + FSTFail(@"Encountered unknown transform: %d type", fieldTransform.transformation().type()); } } return transformResults; @@ -506,17 +483,17 @@ NS_ASSUME_NONNULL_BEGIN - (FSTObjectValue *)transformObject:(FSTObjectValue *)objectValue transformResults:(NSArray *)transformResults { - FSTAssert(transformResults.count == self.fieldTransforms.count, + FSTAssert(transformResults.count == self.fieldTransforms.size(), @"Transform results length mismatch."); - for (NSUInteger i = 0; i < self.fieldTransforms.count; i++) { - FSTFieldTransform *fieldTransform = self.fieldTransforms[i]; - const TransformOperation *transform = fieldTransform.transform; - FieldPath fieldPath = fieldTransform.path; - if (transform->type() == TransformOperation::Type::ServerTimestamp) { + for (size_t i = 0; i < self.fieldTransforms.size(); i++) { + const FieldTransform &fieldTransform = self.fieldTransforms[i]; + const TransformOperation &transform = fieldTransform.transformation(); + const FieldPath &fieldPath = fieldTransform.path(); + if (transform.type() == TransformOperation::Type::ServerTimestamp) { objectValue = [objectValue objectBySettingValue:transformResults[i] forPath:fieldPath]; } else { - FSTFail(@"Encountered unknown transform: %d type", transform->type()); + FSTFail(@"Encountered unknown transform: %d type", transform.type()); } } return objectValue; -- cgit v1.2.3