aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Firestore/Example/Tests/Local/FSTLocalSerializerTests.mm16
-rw-r--r--Firestore/Example/Tests/Model/FSTMutationTests.mm5
-rw-r--r--Firestore/Example/Tests/Remote/FSTSerializerBetaTests.mm4
-rw-r--r--Firestore/Example/Tests/Util/FSTHelpers.mm6
-rw-r--r--Firestore/Source/API/FSTUserDataConverter.h15
-rw-r--r--Firestore/Source/API/FSTUserDataConverter.mm54
-rw-r--r--Firestore/Source/Core/FSTTransaction.h1
-rw-r--r--Firestore/Source/Model/FSTMutation.h38
-rw-r--r--Firestore/Source/Model/FSTMutation.mm64
-rw-r--r--Firestore/Source/Remote/FSTSerializerBeta.mm10
-rw-r--r--Firestore/core/src/firebase/firestore/model/CMakeLists.txt1
-rw-r--r--Firestore/core/src/firebase/firestore/model/field_mask.h97
-rw-r--r--Firestore/core/test/firebase/firestore/model/CMakeLists.txt1
-rw-r--r--Firestore/core/test/firebase/firestore/model/field_mask_test.cc56
14 files changed, 251 insertions, 117 deletions
diff --git a/Firestore/Example/Tests/Local/FSTLocalSerializerTests.mm b/Firestore/Example/Tests/Local/FSTLocalSerializerTests.mm
index d94925d..d810aa6 100644
--- a/Firestore/Example/Tests/Local/FSTLocalSerializerTests.mm
+++ b/Firestore/Example/Tests/Local/FSTLocalSerializerTests.mm
@@ -41,11 +41,13 @@
#import "Firestore/Example/Tests/Util/FSTHelpers.h"
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
+#include "Firestore/core/src/firebase/firestore/model/field_mask.h"
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
#include "Firestore/core/test/firebase/firestore/testutil/testutil.h"
namespace testutil = firebase::firestore::testutil;
using firebase::firestore::model::DatabaseId;
+using firebase::firestore::model::FieldMask;
NS_ASSUME_NONNULL_BEGIN
@@ -76,13 +78,13 @@ NS_ASSUME_NONNULL_BEGIN
- (void)testEncodesMutationBatch {
FSTMutation *set = FSTTestSetMutation(@"foo/bar", @{ @"a" : @"b", @"num" : @1 });
- FSTMutation *patch = [[FSTPatchMutation alloc]
- initWithKey:FSTTestDocKey(@"bar/baz")
- fieldMask:[[FSTFieldMask alloc] initWithFields:{testutil::Field("a")}]
- value:FSTTestObjectValue(
- @{ @"a" : @"b",
- @"num" : @1 })
- precondition:[FSTPrecondition preconditionWithExists:YES]];
+ FSTMutation *patch =
+ [[FSTPatchMutation alloc] initWithKey:FSTTestDocKey(@"bar/baz")
+ fieldMask:FieldMask{testutil::Field("a")}
+ value:FSTTestObjectValue(
+ @{ @"a" : @"b",
+ @"num" : @1 })
+ precondition:[FSTPrecondition preconditionWithExists:YES]];
FSTMutation *del = FSTTestDeleteMutation(@"baz/quux");
FIRTimestamp *writeTime = [FIRTimestamp timestamp];
FSTMutationBatch *model = [[FSTMutationBatch alloc] initWithBatchID:42
diff --git a/Firestore/Example/Tests/Model/FSTMutationTests.mm b/Firestore/Example/Tests/Model/FSTMutationTests.mm
index 1f9193e..9024b22 100644
--- a/Firestore/Example/Tests/Model/FSTMutationTests.mm
+++ b/Firestore/Example/Tests/Model/FSTMutationTests.mm
@@ -25,10 +25,12 @@
#import "Firestore/Example/Tests/Util/FSTHelpers.h"
#include "Firestore/core/src/firebase/firestore/model/document_key.h"
+#include "Firestore/core/src/firebase/firestore/model/field_mask.h"
#include "Firestore/core/test/firebase/firestore/testutil/testutil.h"
namespace testutil = firebase::firestore::testutil;
using firebase::firestore::model::DocumentKey;
+using firebase::firestore::model::FieldMask;
@interface FSTMutationTests : XCTestCase
@end
@@ -69,9 +71,8 @@ using firebase::firestore::model::DocumentKey;
FSTDocument *baseDoc = FSTTestDoc("collection/key", 0, docData, NO);
DocumentKey key = testutil::Key("collection/key");
- FSTFieldMask *mask = [[FSTFieldMask alloc] initWithFields:{testutil::Field("foo.bar")}];
FSTMutation *patch = [[FSTPatchMutation alloc] initWithKey:key
- fieldMask:mask
+ fieldMask:{testutil::Field("foo.bar")}
value:[FSTObjectValue objectValue]
precondition:[FSTPrecondition none]];
FSTMaybeDocument *patchedDoc =
diff --git a/Firestore/Example/Tests/Remote/FSTSerializerBetaTests.mm b/Firestore/Example/Tests/Remote/FSTSerializerBetaTests.mm
index 64f4777..17191f8 100644
--- a/Firestore/Example/Tests/Remote/FSTSerializerBetaTests.mm
+++ b/Firestore/Example/Tests/Remote/FSTSerializerBetaTests.mm
@@ -46,12 +46,14 @@
#import "Firestore/Example/Tests/Util/FSTHelpers.h"
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
+#include "Firestore/core/src/firebase/firestore/model/field_mask.h"
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
#include "Firestore/core/test/firebase/firestore/testutil/testutil.h"
namespace testutil = firebase::firestore::testutil;
namespace util = firebase::firestore::util;
using firebase::firestore::model::DatabaseId;
+using firebase::firestore::model::FieldMask;
NS_ASSUME_NONNULL_BEGIN
@@ -63,7 +65,7 @@ NS_ASSUME_NONNULL_BEGIN
- (GCFSValue *)encodedString:(NSString *)value;
- (GCFSValue *)encodedDate:(NSDate *)value;
-- (GCFSDocumentMask *)encodedFieldMask:(FSTFieldMask *)fieldMask;
+- (GCFSDocumentMask *)encodedFieldMask:(const FieldMask &)fieldMask;
- (NSMutableArray<GCFSDocumentTransform_FieldTransform *> *)encodedFieldTransforms:
(NSArray<FSTFieldTransform *> *)fieldTransforms;
diff --git a/Firestore/Example/Tests/Util/FSTHelpers.mm b/Firestore/Example/Tests/Util/FSTHelpers.mm
index 5751739..8a7306c 100644
--- a/Firestore/Example/Tests/Util/FSTHelpers.mm
+++ b/Firestore/Example/Tests/Util/FSTHelpers.mm
@@ -44,6 +44,7 @@
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
#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_value.h"
#include "Firestore/core/src/firebase/firestore/model/resource_path.h"
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
@@ -53,6 +54,7 @@ namespace util = firebase::firestore::util;
namespace testutil = firebase::firestore::testutil;
using firebase::firestore::model::DatabaseId;
using firebase::firestore::model::DocumentKey;
+using firebase::firestore::model::FieldMask;
using firebase::firestore::model::FieldPath;
using firebase::firestore::model::FieldValue;
using firebase::firestore::model::ResourcePath;
@@ -260,8 +262,8 @@ FSTPatchMutation *FSTTestPatchMutation(const absl::string_view path,
}
}];
- FSTDocumentKey *key = [FSTDocumentKey keyWithPath:testutil::Resource(path)];
- FSTFieldMask *mask = [[FSTFieldMask alloc] initWithFields:merge ? updateMask : fieldMaskPaths];
+ DocumentKey key = testutil::Key(path);
+ FieldMask mask(merge ? updateMask : fieldMaskPaths);
return [[FSTPatchMutation alloc] initWithKey:key
fieldMask:mask
value:objectValue
diff --git a/Firestore/Source/API/FSTUserDataConverter.h b/Firestore/Source/API/FSTUserDataConverter.h
index 3b178be..2b4b340 100644
--- a/Firestore/Source/API/FSTUserDataConverter.h
+++ b/Firestore/Source/API/FSTUserDataConverter.h
@@ -18,10 +18,10 @@
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
#include "Firestore/core/src/firebase/firestore/model/document_key.h"
+#include "Firestore/core/src/firebase/firestore/model/field_mask.h"
@class FIRSetOptions;
@class FSTObjectValue;
-@class FSTFieldMask;
@class FSTFieldValue;
@class FSTFieldTransform;
@class FSTMutation;
@@ -36,13 +36,17 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithData:(FSTObjectValue *)data
- fieldMask:(nullable FSTFieldMask *)fieldMask
+ fieldTransforms:(NSArray<FSTFieldTransform *> *)fieldTransforms
+ NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)initWithData:(FSTObjectValue *)data
+ fieldMask:(firebase::firestore::model::FieldMask)fieldMask
fieldTransforms:(NSArray<FSTFieldTransform *> *)fieldTransforms
NS_DESIGNATED_INITIALIZER;
@property(nonatomic, strong, readonly) FSTObjectValue *data;
-@property(nonatomic, strong, readonly, nullable) FSTFieldMask *fieldMask;
@property(nonatomic, strong, readonly) NSArray<FSTFieldTransform *> *fieldTransforms;
+@property(nonatomic, assign, readonly) BOOL isPatch;
/**
* Converts the parsed document data into 1 or 2 mutations (depending on whether there are any
@@ -59,12 +63,13 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithData:(FSTObjectValue *)data
- fieldMask:(FSTFieldMask *)fieldMask
+ fieldMask:(firebase::firestore::model::FieldMask)fieldMask
fieldTransforms:(NSArray<FSTFieldTransform *> *)fieldTransforms
NS_DESIGNATED_INITIALIZER;
+- (const firebase::firestore::model::FieldMask &)fieldMask;
+
@property(nonatomic, strong, readonly) FSTObjectValue *data;
-@property(nonatomic, strong, readonly) FSTFieldMask *fieldMask;
@property(nonatomic, strong, readonly) NSArray<FSTFieldTransform *> *fieldTransforms;
/**
diff --git a/Firestore/Source/API/FSTUserDataConverter.mm b/Firestore/Source/API/FSTUserDataConverter.mm
index 7ee16de..34f1015 100644
--- a/Firestore/Source/API/FSTUserDataConverter.mm
+++ b/Firestore/Source/API/FSTUserDataConverter.mm
@@ -35,6 +35,7 @@
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
#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/util/string_apple.h"
#include "absl/memory/memory.h"
@@ -42,6 +43,7 @@
namespace util = firebase::firestore::util;
using firebase::firestore::model::DatabaseId;
using firebase::firestore::model::DocumentKey;
+using firebase::firestore::model::FieldMask;
using firebase::firestore::model::FieldPath;
NS_ASSUME_NONNULL_BEGIN
@@ -50,15 +52,30 @@ static NSString *const RESERVED_FIELD_DESIGNATOR = @"__";
#pragma mark - FSTParsedSetData
-@implementation FSTParsedSetData
+@implementation FSTParsedSetData {
+ FieldMask _fieldMask;
+}
+
+- (instancetype)initWithData:(FSTObjectValue *)data
+ fieldTransforms:(NSArray<FSTFieldTransform *> *)fieldTransforms {
+ self = [super init];
+ if (self) {
+ _data = data;
+ _fieldTransforms = fieldTransforms;
+ _isPatch = NO;
+ }
+ return self;
+}
+
- (instancetype)initWithData:(FSTObjectValue *)data
- fieldMask:(nullable FSTFieldMask *)fieldMask
+ fieldMask:(FieldMask)fieldMask
fieldTransforms:(NSArray<FSTFieldTransform *> *)fieldTransforms {
self = [super init];
if (self) {
_data = data;
- _fieldMask = fieldMask;
+ _fieldMask = std::move(fieldMask);
_fieldTransforms = fieldTransforms;
+ _isPatch = YES;
}
return self;
}
@@ -66,9 +83,9 @@ static NSString *const RESERVED_FIELD_DESIGNATOR = @"__";
- (NSArray<FSTMutation *> *)mutationsWithKey:(const DocumentKey &)key
precondition:(FSTPrecondition *)precondition {
NSMutableArray<FSTMutation *> *mutations = [NSMutableArray array];
- if (self.fieldMask) {
+ if (self.isPatch) {
[mutations addObject:[[FSTPatchMutation alloc] initWithKey:key
- fieldMask:self.fieldMask
+ fieldMask:_fieldMask
value:self.data
precondition:precondition]];
} else {
@@ -87,14 +104,17 @@ static NSString *const RESERVED_FIELD_DESIGNATOR = @"__";
#pragma mark - FSTParsedUpdateData
-@implementation FSTParsedUpdateData
+@implementation FSTParsedUpdateData {
+ FieldMask _fieldMask;
+}
+
- (instancetype)initWithData:(FSTObjectValue *)data
- fieldMask:(FSTFieldMask *)fieldMask
+ fieldMask:(FieldMask)fieldMask
fieldTransforms:(NSArray<FSTFieldTransform *> *)fieldTransforms {
self = [super init];
if (self) {
_data = data;
- _fieldMask = fieldMask;
+ _fieldMask = std::move(fieldMask);
_fieldTransforms = fieldTransforms;
}
return self;
@@ -114,6 +134,10 @@ static NSString *const RESERVED_FIELD_DESIGNATOR = @"__";
return mutations;
}
+- (const firebase::firestore::model::FieldMask &)fieldMask {
+ return _fieldMask;
+}
+
@end
/**
@@ -364,10 +388,9 @@ typedef NS_ENUM(NSInteger, FSTUserDataSource) {
path:absl::make_unique<FieldPath>(FieldPath::EmptyPath())];
FSTObjectValue *updateData = (FSTObjectValue *)[self parseData:input context:context];
- return [[FSTParsedSetData alloc]
- initWithData:updateData
- fieldMask:[[FSTFieldMask alloc] initWithFields:*context.fieldMask]
- fieldTransforms:context.fieldTransforms];
+ return [[FSTParsedSetData alloc] initWithData:updateData
+ fieldMask:FieldMask{*context.fieldMask}
+ fieldTransforms:context.fieldTransforms];
}
- (FSTParsedSetData *)parsedSetData:(id)input {
@@ -382,9 +405,7 @@ typedef NS_ENUM(NSInteger, FSTUserDataSource) {
path:absl::make_unique<FieldPath>(FieldPath::EmptyPath())];
FSTObjectValue *updateData = (FSTObjectValue *)[self parseData:input context:context];
- return [[FSTParsedSetData alloc] initWithData:updateData
- fieldMask:nil
- fieldTransforms:context.fieldTransforms];
+ return [[FSTParsedSetData alloc] initWithData:updateData fieldTransforms:context.fieldTransforms];
}
- (FSTParsedUpdateData *)parsedUpdateData:(id)input {
@@ -428,9 +449,8 @@ typedef NS_ENUM(NSInteger, FSTUserDataSource) {
}
}];
- FSTFieldMask *mask = [[FSTFieldMask alloc] initWithFields:fieldMaskPaths];
return [[FSTParsedUpdateData alloc] initWithData:updateData
- fieldMask:mask
+ fieldMask:FieldMask{fieldMaskPaths}
fieldTransforms:context.fieldTransforms];
}
diff --git a/Firestore/Source/Core/FSTTransaction.h b/Firestore/Source/Core/FSTTransaction.h
index 676ada9..01c2e20 100644
--- a/Firestore/Source/Core/FSTTransaction.h
+++ b/Firestore/Source/Core/FSTTransaction.h
@@ -24,7 +24,6 @@
@class FIRSetOptions;
@class FSTDatastore;
-@class FSTFieldMask;
@class FSTFieldTransform;
@class FSTMaybeDocument;
@class FSTObjectValue;
diff --git a/Firestore/Source/Model/FSTMutation.h b/Firestore/Source/Model/FSTMutation.h
index 4e4357d..2b81af6 100644
--- a/Firestore/Source/Model/FSTMutation.h
+++ b/Firestore/Source/Model/FSTMutation.h
@@ -19,6 +19,7 @@
#include <vector>
#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"
@class FSTDocument;
@@ -30,31 +31,6 @@
NS_ASSUME_NONNULL_BEGIN
-#pragma mark - FSTFieldMask
-
-/**
- * Provides a set of fields that can be used to partially patch a document. FieldMask is used in
- * conjunction with ObjectValue.
- *
- * Examples:
- * foo - Overwrites foo entirely with the provided value. If foo is not present in the companion
- * ObjectValue, the field is deleted.
- * foo.bar - Overwrites only the field bar of the object foo. If foo is not an object, foo is
- * replaced with an object containing bar.
- */
-@interface FSTFieldMask : NSObject
-- (id)init __attribute__((unavailable("Use initWithFields:")));
-
-/**
- * Initializes the field mask with the given field paths. Caller is expected to either copy or
- * or release the array of fields.
- */
-- (instancetype)initWithFields:(std::vector<firebase::firestore::model::FieldPath>)fields
- NS_DESIGNATED_INITIALIZER;
-
-- (const std::vector<firebase::firestore::model::FieldPath> &)fields;
-@end
-
#pragma mark - FSTFieldTransform
/** Represents a transform within a TransformMutation. */
@@ -267,7 +243,7 @@ typedef NS_ENUM(NSUInteger, FSTPreconditionExists) {
precondition:(FSTPrecondition *)precondition NS_UNAVAILABLE;
/**
- * Initializes a new patch mutation with an explicit FSTFieldMask and FSTObjectValue representing
+ * Initializes a new patch mutation with an explicit FieldMask and FSTObjectValue representing
* the updates to perform
*
* @param key Identifies the location of the document to mutate.
@@ -278,18 +254,18 @@ typedef NS_ENUM(NSUInteger, FSTPreconditionExists) {
* @param precondition The precondition for this mutation.
*/
- (instancetype)initWithKey:(firebase::firestore::model::DocumentKey)key
- fieldMask:(FSTFieldMask *)fieldMask
+ fieldMask:(firebase::firestore::model::FieldMask)fieldMask
value:(FSTObjectValue *)value
precondition:(FSTPrecondition *)precondition NS_DESIGNATED_INITIALIZER;
-/** The fields and associated values to use when patching the document. */
-@property(nonatomic, strong, readonly) FSTObjectValue *value;
-
/**
* A mask to apply to |value|, where only fields that are in both the fieldMask and the value
* will be updated.
*/
-@property(nonatomic, strong, readonly) FSTFieldMask *fieldMask;
+- (const firebase::firestore::model::FieldMask &)fieldMask;
+
+/** The fields and associated values to use when patching the document. */
+@property(nonatomic, strong, readonly) FSTObjectValue *value;
@end
diff --git a/Firestore/Source/Model/FSTMutation.mm b/Firestore/Source/Model/FSTMutation.mm
index 253a853..df95155 100644
--- a/Firestore/Source/Model/FSTMutation.mm
+++ b/Firestore/Source/Model/FSTMutation.mm
@@ -27,51 +27,15 @@
#import "Firestore/Source/Util/FSTClasses.h"
#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"
using firebase::firestore::model::DocumentKey;
+using firebase::firestore::model::FieldMask;
using firebase::firestore::model::FieldPath;
NS_ASSUME_NONNULL_BEGIN
-#pragma mark - FSTFieldMask
-
-@implementation FSTFieldMask {
- std::vector<FieldPath> _fields;
-}
-
-- (instancetype)initWithFields:(std::vector<FieldPath>)fields {
- if (self = [super init]) {
- _fields = std::move(fields);
- }
- return self;
-}
-
-- (BOOL)isEqual:(id)other {
- if (other == self) {
- return YES;
- }
- if (![other isKindOfClass:[FSTFieldMask class]]) {
- return NO;
- }
-
- FSTFieldMask *otherMask = (FSTFieldMask *)other;
- return _fields == otherMask->_fields;
-}
-
-- (NSUInteger)hash {
- NSUInteger hashResult = 0;
- for (const FieldPath &field : _fields) {
- hashResult = hashResult * 31u + field.Hash();
- }
- return hashResult;
-}
-
-- (const std::vector<FieldPath> &)fields {
- return _fields;
-}
-@end
-
#pragma mark - FSTServerTimestampTransform
@implementation FSTServerTimestampTransform
@@ -354,20 +318,26 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - FSTPatchMutation
-@implementation FSTPatchMutation
+@implementation FSTPatchMutation {
+ FieldMask _fieldMask;
+}
- (instancetype)initWithKey:(DocumentKey)key
- fieldMask:(FSTFieldMask *)fieldMask
+ fieldMask:(FieldMask)fieldMask
value:(FSTObjectValue *)value
precondition:(FSTPrecondition *)precondition {
self = [super initWithKey:std::move(key) precondition:precondition];
if (self) {
- _fieldMask = fieldMask;
+ _fieldMask = std::move(fieldMask);
_value = value;
}
return self;
}
+- (const firebase::firestore::model::FieldMask &)fieldMask {
+ return _fieldMask;
+}
+
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
@@ -377,7 +347,7 @@ NS_ASSUME_NONNULL_BEGIN
}
FSTPatchMutation *otherMutation = (FSTPatchMutation *)other;
- return [self.key isEqual:otherMutation.key] && [self.fieldMask isEqual:otherMutation.fieldMask] &&
+ return [self.key isEqual:otherMutation.key] && self.fieldMask == otherMutation.fieldMask &&
[self.value isEqual:otherMutation.value] &&
[self.precondition isEqual:otherMutation.precondition];
}
@@ -385,15 +355,15 @@ NS_ASSUME_NONNULL_BEGIN
- (NSUInteger)hash {
NSUInteger result = [self.key hash];
result = 31 * result + [self.precondition hash];
- result = 31 * result + [self.fieldMask hash];
+ result = 31 * result + self.fieldMask.Hash();
result = 31 * result + [self.value hash];
return result;
}
- (NSString *)description {
- return [NSString stringWithFormat:@"<FSTPatchMutation key=%s mask=%@ value=%@ precondition=%@>",
- self.key.ToString().c_str(), self.fieldMask, self.value,
- self.precondition];
+ return [NSString stringWithFormat:@"<FSTPatchMutation key=%s mask=%s value=%@ precondition=%@>",
+ self.key.ToString().c_str(), self.fieldMask.ToString().c_str(),
+ self.value, self.precondition];
}
- (nullable FSTMaybeDocument *)applyTo:(nullable FSTMaybeDocument *)maybeDoc
@@ -434,7 +404,7 @@ NS_ASSUME_NONNULL_BEGIN
- (FSTObjectValue *)patchObjectValue:(FSTObjectValue *)objectValue {
FSTObjectValue *result = objectValue;
- for (const FieldPath &fieldPath : self.fieldMask.fields) {
+ for (const FieldPath &fieldPath : self.fieldMask) {
FSTFieldValue *newValue = [self.value valueForPath:fieldPath];
if (newValue) {
result = [result objectBySettingValue:newValue forPath:fieldPath];
diff --git a/Firestore/Source/Remote/FSTSerializerBeta.mm b/Firestore/Source/Remote/FSTSerializerBeta.mm
index 3a22a3f..3b6f052 100644
--- a/Firestore/Source/Remote/FSTSerializerBeta.mm
+++ b/Firestore/Source/Remote/FSTSerializerBeta.mm
@@ -44,6 +44,7 @@
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
#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/resource_path.h"
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
@@ -51,6 +52,7 @@
namespace util = firebase::firestore::util;
using firebase::firestore::model::DatabaseId;
using firebase::firestore::model::DocumentKey;
+using firebase::firestore::model::FieldMask;
using firebase::firestore::model::FieldPath;
using firebase::firestore::model::ResourcePath;
@@ -539,21 +541,21 @@ NS_ASSUME_NONNULL_BEGIN
}
}
-- (GCFSDocumentMask *)encodedFieldMask:(FSTFieldMask *)fieldMask {
+- (GCFSDocumentMask *)encodedFieldMask:(const FieldMask &)fieldMask {
GCFSDocumentMask *mask = [GCFSDocumentMask message];
- for (const FieldPath &field : fieldMask.fields) {
+ for (const FieldPath &field : fieldMask) {
[mask.fieldPathsArray addObject:util::WrapNSString(field.CanonicalString())];
}
return mask;
}
-- (FSTFieldMask *)decodedFieldMask:(GCFSDocumentMask *)fieldMask {
+- (FieldMask)decodedFieldMask:(GCFSDocumentMask *)fieldMask {
std::vector<FieldPath> fields{};
fields.reserve(fieldMask.fieldPathsArray_Count);
for (NSString *path in fieldMask.fieldPathsArray) {
fields.push_back(FieldPath::FromServerFormat(util::MakeStringView(path)));
}
- return [[FSTFieldMask alloc] initWithFields:std::move(fields)];
+ return FieldMask(std::move(fields));
}
- (NSMutableArray<GCFSDocumentTransform_FieldTransform *> *)encodedFieldTransforms:
diff --git a/Firestore/core/src/firebase/firestore/model/CMakeLists.txt b/Firestore/core/src/firebase/firestore/model/CMakeLists.txt
index 78f5cd6..f6c5efe 100644
--- a/Firestore/core/src/firebase/firestore/model/CMakeLists.txt
+++ b/Firestore/core/src/firebase/firestore/model/CMakeLists.txt
@@ -22,6 +22,7 @@ cc_library(
document.h
document_key.cc
document_key.h
+ field_mask.h
field_path.cc
field_path.h
field_value.cc
diff --git a/Firestore/core/src/firebase/firestore/model/field_mask.h b/Firestore/core/src/firebase/firestore/model/field_mask.h
new file mode 100644
index 0000000..a9f509a
--- /dev/null
+++ b/Firestore/core/src/firebase/firestore/model/field_mask.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2018 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_FIELD_MASK_H_
+#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_FIELD_MASK_H_
+
+#include <initializer_list>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "Firestore/core/src/firebase/firestore/model/field_path.h"
+
+namespace firebase {
+namespace firestore {
+namespace model {
+
+/**
+ * Provides a set of fields that can be used to partially patch a document.
+ * FieldMask is used in conjunction with FieldValue of Object type.
+ *
+ * Examples:
+ * foo - Overwrites foo entirely with the provided value. If foo is not
+ * present in the companion FieldValue, the field is deleted.
+ * foo.bar - Overwrites only the field bar of the object foo. If foo is not an
+ * object, foo is replaced with an object containing bar.
+ */
+class FieldMask {
+ public:
+ using const_iterator = std::vector<FieldPath>::const_iterator;
+
+ FieldMask(std::initializer_list<FieldPath> list) : fields_{list} {
+ }
+ explicit FieldMask(const std::vector<FieldPath>& fields) : fields_{fields} {
+ }
+ explicit FieldMask(std::vector<FieldPath>&& fields)
+ : fields_{std::move(fields)} {
+ }
+
+ const_iterator begin() const {
+ return fields_.begin();
+ }
+ const_iterator end() const {
+ return fields_.end();
+ }
+
+ std::string ToString() const {
+ // Ideally, one should use a string builder. Since this is only non-critical
+ // code for logging and debugging, the logic is kept simple here.
+ std::string result("{ ");
+ for (const FieldPath& field : fields_) {
+ result += field.CanonicalString() + " ";
+ }
+ return result + "}";
+ }
+
+#if defined(__OBJC__)
+ FieldMask() {
+ }
+
+ NSUInteger Hash() const {
+ NSUInteger hashResult = 0;
+ for (const FieldPath& field : fields_) {
+ hashResult = hashResult * 31u + field.Hash();
+ }
+ return hashResult;
+ }
+#endif
+
+ friend bool operator==(const FieldMask& lhs, const FieldMask& rhs);
+
+ private:
+ std::vector<FieldPath> fields_;
+};
+
+inline bool operator==(const FieldMask& lhs, const FieldMask& rhs) {
+ return lhs.fields_ == rhs.fields_;
+}
+
+} // namespace model
+} // namespace firestore
+} // namespace firebase
+
+#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_FIELD_MASK_H_
diff --git a/Firestore/core/test/firebase/firestore/model/CMakeLists.txt b/Firestore/core/test/firebase/firestore/model/CMakeLists.txt
index 2c2281f..59a1f03 100644
--- a/Firestore/core/test/firebase/firestore/model/CMakeLists.txt
+++ b/Firestore/core/test/firebase/firestore/model/CMakeLists.txt
@@ -18,6 +18,7 @@ cc_test(
database_id_test.cc
document_key_test.cc
document_test.cc
+ field_mask_test.cc
field_path_test.cc
field_value_test.cc
maybe_document_test.cc
diff --git a/Firestore/core/test/firebase/firestore/model/field_mask_test.cc b/Firestore/core/test/firebase/firestore/model/field_mask_test.cc
new file mode 100644
index 0000000..52d5951
--- /dev/null
+++ b/Firestore/core/test/firebase/firestore/model/field_mask_test.cc
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2018 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Firestore/core/src/firebase/firestore/model/field_mask.h"
+
+#include <vector>
+
+#include "Firestore/core/src/firebase/firestore/model/field_path.h"
+#include "gtest/gtest.h"
+
+namespace firebase {
+namespace firestore {
+namespace model {
+
+TEST(FieldMask, ConstructorAndEqual) {
+ FieldMask mask_a{FieldPath::FromServerFormat("foo"),
+ FieldPath::FromServerFormat("bar")};
+ std::vector<FieldPath> field_path_vector{FieldPath::FromServerFormat("foo"),
+ FieldPath::FromServerFormat("bar")};
+ FieldMask mask_b{field_path_vector};
+ FieldMask mask_c{std::vector<FieldPath>{FieldPath::FromServerFormat("foo"),
+ FieldPath::FromServerFormat("bar")}};
+ EXPECT_EQ(mask_a, mask_b);
+ EXPECT_EQ(mask_b, mask_c);
+}
+
+TEST(FieldMask, Getter) {
+ FieldMask mask{FieldPath::FromServerFormat("foo"),
+ FieldPath::FromServerFormat("bar")};
+ EXPECT_EQ(std::vector<FieldPath>({FieldPath::FromServerFormat("foo"),
+ FieldPath::FromServerFormat("bar")}),
+ std::vector<FieldPath>(mask.begin(), mask.end()));
+}
+
+TEST(FieldMask, ToString) {
+ FieldMask mask{FieldPath::FromServerFormat("foo"),
+ FieldPath::FromServerFormat("bar")};
+ EXPECT_EQ("{ foo bar }", mask.ToString());
+}
+
+} // namespace model
+} // namespace firestore
+} // namespace firebase