diff options
Diffstat (limited to 'Firestore/core/src/firebase/firestore/model/transform_operations.h')
-rw-r--r-- | Firestore/core/src/firebase/firestore/model/transform_operations.h | 94 |
1 files changed, 81 insertions, 13 deletions
diff --git a/Firestore/core/src/firebase/firestore/model/transform_operations.h b/Firestore/core/src/firebase/firestore/model/transform_operations.h index a1c2de0..8eed7ae 100644 --- a/Firestore/core/src/firebase/firestore/model/transform_operations.h +++ b/Firestore/core/src/firebase/firestore/model/transform_operations.h @@ -17,12 +17,16 @@ #ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_TRANSFORM_OPERATIONS_H_ #define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_TRANSFORM_OPERATIONS_H_ +#if !defined(__OBJC__) +#error "This header only supports Objective-C++." +#endif // !defined(__OBJC__) + #include <utility> #include <vector> -#if defined(__OBJC__) #import "Firestore/Source/Model/FSTFieldValue.h" -#endif + +#include "Firestore/core/include/firebase/firestore/timestamp.h" namespace firebase { namespace firestore { @@ -49,6 +53,20 @@ class TransformOperation { /** Returns the actual type. */ virtual Type type() const = 0; + /** + * Computes the local transform result against the provided `previousValue`, + * optionally using the provided localWriteTime. + */ + virtual FSTFieldValue* ApplyToLocalView( + FSTFieldValue* previousValue, FIRTimestamp* localWriteTime) const = 0; + + /** + * Computes a final transform result after the transform has been acknowledged + * by the server, potentially using the server-provided transformResult. + */ + virtual FSTFieldValue* ApplyToRemoteDocument( + FSTFieldValue* previousValue, FSTFieldValue* transformResult) const = 0; + /** Returns whether the two are equal. */ virtual bool operator==(const TransformOperation& other) const = 0; @@ -57,11 +75,9 @@ class TransformOperation { return !operator==(other); } -#if defined(__OBJC__) // For Objective-C++ hash; to be removed after migration. // Do NOT use in C++ code. virtual NSUInteger Hash() const = 0; -#endif // defined(__OBJC__) }; /** Transforms a value into a server-generated timestamp. */ @@ -74,6 +90,19 @@ class ServerTimestampTransform : public TransformOperation { return Type::ServerTimestamp; } + FSTFieldValue* ApplyToLocalView(FSTFieldValue* previousValue, + FIRTimestamp* localWriteTime) const override { + return [FSTServerTimestampValue + serverTimestampValueWithLocalWriteTime:localWriteTime + previousValue:previousValue]; + } + + FSTFieldValue* ApplyToRemoteDocument( + FSTFieldValue* /* previousValue */, + FSTFieldValue* transformResult) const override { + return transformResult; + } + bool operator==(const TransformOperation& other) const override { // All ServerTimestampTransform objects are equal. return other.type() == Type::ServerTimestamp; @@ -84,7 +113,6 @@ class ServerTimestampTransform : public TransformOperation { return shared_instance; } -#if defined(__OBJC__) // For Objective-C++ hash; to be removed after migration. // Do NOT use in C++ code. NSUInteger Hash() const override { @@ -92,16 +120,12 @@ class ServerTimestampTransform : public TransformOperation { // instances are equal. return 37; } -#endif // defined(__OBJC__) private: ServerTimestampTransform() { } }; -// TODO(mikelehen): ArrayTransform can only be used from Obj-C until we switch -// to using FieldValue instead of FSTFieldValue. -#if defined(__OBJC__) /** * Transforms an array via a union or remove operation (for convenience, we use * this class for both Type::ArrayUnion and Type::ArrayRemove). @@ -119,6 +143,21 @@ class ArrayTransform : public TransformOperation { return type_; } + FSTFieldValue* ApplyToLocalView( + FSTFieldValue* previousValue, + FIRTimestamp* /* localWriteTime */) const override { + return Apply(previousValue); + } + + FSTFieldValue* ApplyToRemoteDocument( + FSTFieldValue* previousValue, + FSTFieldValue* /* transformResult */) const override { + // The server just sends null as the transform result for array operations, + // so we have to calculate a result the same as we do for local + // applications. + return Apply(previousValue); + } + const std::vector<FSTFieldValue*>& elements() const { return elements_; } @@ -131,7 +170,7 @@ class ArrayTransform : public TransformOperation { if (array_transform.elements_.size() != elements_.size()) { return false; } - for (int i = 0; i < elements_.size(); i++) { + for (size_t i = 0; i < elements_.size(); i++) { if (![array_transform.elements_[i] isEqual:elements_[i]]) { return false; } @@ -139,7 +178,6 @@ class ArrayTransform : public TransformOperation { return true; } -#if defined(__OBJC__) // For Objective-C++ hash; to be removed after migration. // Do NOT use in C++ code. NSUInteger Hash() const override { @@ -150,7 +188,6 @@ class ArrayTransform : public TransformOperation { } return result; } -#endif // defined(__OBJC__) static const std::vector<FSTFieldValue*>& Elements( const TransformOperation& op) { @@ -162,8 +199,39 @@ class ArrayTransform : public TransformOperation { private: Type type_; std::vector<FSTFieldValue*> elements_; + + /** + * Inspects the provided value, returning a mutable copy of the internal array + * if it's an FSTArrayValue and an empty mutable array if it's nil or any + * other type of FSTFieldValue. + */ + static NSMutableArray<FSTFieldValue*>* CoercedFieldValuesArray( + FSTFieldValue* value) { + if ([value isMemberOfClass:[FSTArrayValue class]]) { + return [NSMutableArray + arrayWithArray:reinterpret_cast<FSTArrayValue*>(value).internalValue]; + } else { + // coerce to empty array. + return [NSMutableArray array]; + } + } + + FSTFieldValue* Apply(FSTFieldValue* previousValue) const { + NSMutableArray<FSTFieldValue*>* result = + ArrayTransform::CoercedFieldValuesArray(previousValue); + for (FSTFieldValue* element : elements_) { + if (type_ == Type::ArrayUnion) { + if (![result containsObject:element]) { + [result addObject:element]; + } + } else { + FIREBASE_ASSERT(type_ == Type::ArrayRemove); + [result removeObject:element]; + } + } + return [[FSTArrayValue alloc] initWithValueNoCopy:result]; + } }; -#endif } // namespace model } // namespace firestore |