aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/core/src/firebase/firestore/model/transform_operations.h
diff options
context:
space:
mode:
Diffstat (limited to 'Firestore/core/src/firebase/firestore/model/transform_operations.h')
-rw-r--r--Firestore/core/src/firebase/firestore/model/transform_operations.h94
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