FSTDocument.mm 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * Copyright 2017 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import "Firestore/Source/Model/FSTDocument.h"
  17. #include <utility>
  18. #import "Firestore/Source/Model/FSTFieldValue.h"
  19. #import "Firestore/Source/Util/FSTClasses.h"
  20. #include "Firestore/core/src/firebase/firestore/model/document_key.h"
  21. #include "Firestore/core/src/firebase/firestore/model/field_path.h"
  22. #include "Firestore/core/src/firebase/firestore/util/hard_assert.h"
  23. #include "Firestore/core/src/firebase/firestore/util/hashing.h"
  24. #include "Firestore/core/src/firebase/firestore/util/string_apple.h"
  25. namespace util = firebase::firestore::util;
  26. using firebase::firestore::model::DocumentKey;
  27. using firebase::firestore::model::FieldPath;
  28. using firebase::firestore::model::SnapshotVersion;
  29. NS_ASSUME_NONNULL_BEGIN
  30. @interface FSTMaybeDocument ()
  31. - (instancetype)initWithKey:(DocumentKey)key
  32. version:(SnapshotVersion)version NS_DESIGNATED_INITIALIZER;
  33. @end
  34. @implementation FSTMaybeDocument {
  35. DocumentKey _key;
  36. SnapshotVersion _version;
  37. }
  38. - (instancetype)initWithKey:(DocumentKey)key version:(SnapshotVersion)version {
  39. self = [super init];
  40. if (self) {
  41. _key = std::move(key);
  42. _version = std::move(version);
  43. }
  44. return self;
  45. }
  46. - (BOOL)hasPendingWrites {
  47. @throw FSTAbstractMethodException(); // NOLINT
  48. }
  49. - (id)copyWithZone:(NSZone *_Nullable)zone {
  50. // All document types are immutable
  51. return self;
  52. }
  53. - (const DocumentKey &)key {
  54. return _key;
  55. }
  56. - (const SnapshotVersion &)version {
  57. return _version;
  58. }
  59. @end
  60. @implementation FSTDocument {
  61. FSTDocumentState _documentState;
  62. }
  63. + (instancetype)documentWithData:(FSTObjectValue *)data
  64. key:(DocumentKey)key
  65. version:(SnapshotVersion)version
  66. state:(FSTDocumentState)state {
  67. return [[FSTDocument alloc] initWithData:data
  68. key:std::move(key)
  69. version:std::move(version)
  70. state:state];
  71. }
  72. - (instancetype)initWithData:(FSTObjectValue *)data
  73. key:(DocumentKey)key
  74. version:(SnapshotVersion)version
  75. state:(FSTDocumentState)state {
  76. self = [super initWithKey:std::move(key) version:std::move(version)];
  77. if (self) {
  78. _data = data;
  79. _documentState = state;
  80. }
  81. return self;
  82. }
  83. - (BOOL)hasLocalMutations {
  84. return _documentState == FSTDocumentStateLocalMutations;
  85. }
  86. - (BOOL)hasCommittedMutations {
  87. return _documentState == FSTDocumentStateCommittedMutations;
  88. }
  89. - (BOOL)hasPendingWrites {
  90. return self.hasLocalMutations || self.hasCommittedMutations;
  91. }
  92. - (BOOL)isEqual:(id)other {
  93. if (other == self) {
  94. return YES;
  95. }
  96. if (![other isKindOfClass:[FSTDocument class]]) {
  97. return NO;
  98. }
  99. FSTDocument *otherDoc = other;
  100. return self.key == otherDoc.key && self.version == otherDoc.version &&
  101. _documentState == otherDoc->_documentState && [self.data isEqual:otherDoc.data];
  102. }
  103. - (NSUInteger)hash {
  104. NSUInteger result = [self.key hash];
  105. result = result * 31 + self.version.Hash();
  106. result = result * 31 + [self.data hash];
  107. result = result * 31 + _documentState;
  108. return result;
  109. }
  110. - (NSString *)description {
  111. return [NSString stringWithFormat:@"<FSTDocument: key:%s version:%s documentState:%ld data:%@>",
  112. self.key.ToString().c_str(),
  113. self.version.timestamp().ToString().c_str(),
  114. (long)_documentState, self.data];
  115. }
  116. - (nullable FSTFieldValue *)fieldForPath:(const FieldPath &)path {
  117. return [_data valueForPath:path];
  118. }
  119. @end
  120. @implementation FSTDeletedDocument {
  121. BOOL _hasCommittedMutations;
  122. }
  123. + (instancetype)documentWithKey:(DocumentKey)key
  124. version:(SnapshotVersion)version
  125. hasCommittedMutations:(BOOL)committedMutations {
  126. FSTDeletedDocument *deletedDocument =
  127. [[FSTDeletedDocument alloc] initWithKey:std::move(key) version:std::move(version)];
  128. if (deletedDocument) {
  129. deletedDocument->_hasCommittedMutations = committedMutations;
  130. }
  131. return deletedDocument;
  132. }
  133. - (BOOL)hasCommittedMutations {
  134. return _hasCommittedMutations;
  135. }
  136. - (BOOL)hasPendingWrites {
  137. return self.hasCommittedMutations;
  138. }
  139. - (BOOL)isEqual:(id)other {
  140. if (other == self) {
  141. return YES;
  142. }
  143. if (![other isKindOfClass:[FSTDeletedDocument class]]) {
  144. return NO;
  145. }
  146. FSTDeletedDocument *otherDoc = other;
  147. return self.key == otherDoc.key && self.version == otherDoc.version &&
  148. _hasCommittedMutations == otherDoc->_hasCommittedMutations;
  149. }
  150. - (NSUInteger)hash {
  151. NSUInteger result = [self.key hash];
  152. result = result * 31 + self.version.Hash();
  153. result = result * 31 + (_hasCommittedMutations ? 1 : 0);
  154. return result;
  155. }
  156. - (NSString *)description {
  157. return [NSString
  158. stringWithFormat:@"<FSTDeletedDocument: key:%s version:%s committedMutations:%d>",
  159. self.key.ToString().c_str(), self.version.timestamp().ToString().c_str(),
  160. _hasCommittedMutations];
  161. }
  162. @end
  163. @implementation FSTUnknownDocument
  164. + (instancetype)documentWithKey:(DocumentKey)key version:(SnapshotVersion)version {
  165. return [[FSTUnknownDocument alloc] initWithKey:std::move(key) version:std::move(version)];
  166. }
  167. - (BOOL)hasPendingWrites {
  168. return YES;
  169. }
  170. - (BOOL)isEqual:(id)other {
  171. if (other == self) {
  172. return YES;
  173. }
  174. if (![other isKindOfClass:[FSTUnknownDocument class]]) {
  175. return NO;
  176. }
  177. FSTDocument *otherDoc = other;
  178. return self.key == otherDoc.key && self.version == otherDoc.version;
  179. }
  180. - (NSUInteger)hash {
  181. NSUInteger result = [self.key hash];
  182. result = result * 31 + self.version.Hash();
  183. return result;
  184. }
  185. - (NSString *)description {
  186. return [NSString stringWithFormat:@"<FSTUnknownDocument: key:%s version:%s>",
  187. self.key.ToString().c_str(),
  188. self.version.timestamp().ToString().c_str()];
  189. }
  190. @end
  191. const NSComparator FSTDocumentComparatorByKey =
  192. ^NSComparisonResult(FSTMaybeDocument *doc1, FSTMaybeDocument *doc2) {
  193. return [doc1.key compare:doc2.key];
  194. };
  195. NS_ASSUME_NONNULL_END