FSTDocument.mm 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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)documentWithData:(FSTObjectValue *)data
  73. key:(DocumentKey)key
  74. version:(SnapshotVersion)version
  75. state:(FSTDocumentState)state
  76. proto:(GCFSDocument *)proto {
  77. return [[FSTDocument alloc] initWithData:data
  78. key:std::move(key)
  79. version:std::move(version)
  80. state:state
  81. proto:proto];
  82. }
  83. - (instancetype)initWithData:(FSTObjectValue *)data
  84. key:(DocumentKey)key
  85. version:(SnapshotVersion)version
  86. state:(FSTDocumentState)state {
  87. self = [super initWithKey:std::move(key) version:std::move(version)];
  88. if (self) {
  89. _data = data;
  90. _documentState = state;
  91. _proto = nil;
  92. }
  93. return self;
  94. }
  95. - (instancetype)initWithData:(FSTObjectValue *)data
  96. key:(DocumentKey)key
  97. version:(SnapshotVersion)version
  98. state:(FSTDocumentState)state
  99. proto:(GCFSDocument *)proto {
  100. self = [super initWithKey:std::move(key) version:std::move(version)];
  101. if (self) {
  102. _data = data;
  103. _documentState = state;
  104. _proto = proto;
  105. }
  106. return self;
  107. }
  108. - (BOOL)hasLocalMutations {
  109. return _documentState == FSTDocumentStateLocalMutations;
  110. }
  111. - (BOOL)hasCommittedMutations {
  112. return _documentState == FSTDocumentStateCommittedMutations;
  113. }
  114. - (BOOL)hasPendingWrites {
  115. return self.hasLocalMutations || self.hasCommittedMutations;
  116. }
  117. - (BOOL)isEqual:(id)other {
  118. if (other == self) {
  119. return YES;
  120. }
  121. if (![other isKindOfClass:[FSTDocument class]]) {
  122. return NO;
  123. }
  124. FSTDocument *otherDoc = other;
  125. return self.key == otherDoc.key && self.version == otherDoc.version &&
  126. _documentState == otherDoc->_documentState && [self.data isEqual:otherDoc.data];
  127. }
  128. - (NSUInteger)hash {
  129. NSUInteger result = [self.key hash];
  130. result = result * 31 + self.version.Hash();
  131. result = result * 31 + [self.data hash];
  132. result = result * 31 + _documentState;
  133. return result;
  134. }
  135. - (NSString *)description {
  136. return [NSString stringWithFormat:@"<FSTDocument: key:%s version:%s documentState:%ld data:%@>",
  137. self.key.ToString().c_str(),
  138. self.version.timestamp().ToString().c_str(),
  139. (long)_documentState, self.data];
  140. }
  141. - (nullable FSTFieldValue *)fieldForPath:(const FieldPath &)path {
  142. return [_data valueForPath:path];
  143. }
  144. @end
  145. @implementation FSTDeletedDocument {
  146. BOOL _hasCommittedMutations;
  147. }
  148. + (instancetype)documentWithKey:(DocumentKey)key
  149. version:(SnapshotVersion)version
  150. hasCommittedMutations:(BOOL)committedMutations {
  151. FSTDeletedDocument *deletedDocument = [[FSTDeletedDocument alloc] initWithKey:std::move(key)
  152. version:std::move(version)];
  153. if (deletedDocument) {
  154. deletedDocument->_hasCommittedMutations = committedMutations;
  155. }
  156. return deletedDocument;
  157. }
  158. - (BOOL)hasCommittedMutations {
  159. return _hasCommittedMutations;
  160. }
  161. - (BOOL)hasPendingWrites {
  162. return self.hasCommittedMutations;
  163. }
  164. - (BOOL)isEqual:(id)other {
  165. if (other == self) {
  166. return YES;
  167. }
  168. if (![other isKindOfClass:[FSTDeletedDocument class]]) {
  169. return NO;
  170. }
  171. FSTDeletedDocument *otherDoc = other;
  172. return self.key == otherDoc.key && self.version == otherDoc.version &&
  173. _hasCommittedMutations == otherDoc->_hasCommittedMutations;
  174. }
  175. - (NSUInteger)hash {
  176. NSUInteger result = [self.key hash];
  177. result = result * 31 + self.version.Hash();
  178. result = result * 31 + (_hasCommittedMutations ? 1 : 0);
  179. return result;
  180. }
  181. - (NSString *)description {
  182. return [NSString
  183. stringWithFormat:@"<FSTDeletedDocument: key:%s version:%s committedMutations:%d>",
  184. self.key.ToString().c_str(), self.version.timestamp().ToString().c_str(),
  185. _hasCommittedMutations];
  186. }
  187. @end
  188. @implementation FSTUnknownDocument
  189. + (instancetype)documentWithKey:(DocumentKey)key version:(SnapshotVersion)version {
  190. return [[FSTUnknownDocument alloc] initWithKey:std::move(key) version:std::move(version)];
  191. }
  192. - (BOOL)hasPendingWrites {
  193. return YES;
  194. }
  195. - (BOOL)isEqual:(id)other {
  196. if (other == self) {
  197. return YES;
  198. }
  199. if (![other isKindOfClass:[FSTUnknownDocument class]]) {
  200. return NO;
  201. }
  202. FSTDocument *otherDoc = other;
  203. return self.key == otherDoc.key && self.version == otherDoc.version;
  204. }
  205. - (NSUInteger)hash {
  206. NSUInteger result = [self.key hash];
  207. result = result * 31 + self.version.Hash();
  208. return result;
  209. }
  210. - (NSString *)description {
  211. return [NSString stringWithFormat:@"<FSTUnknownDocument: key:%s version:%s>",
  212. self.key.ToString().c_str(),
  213. self.version.timestamp().ToString().c_str()];
  214. }
  215. @end
  216. const NSComparator FSTDocumentComparatorByKey =
  217. ^NSComparisonResult(FSTMaybeDocument *doc1, FSTMaybeDocument *doc2) {
  218. return CompareKeys(doc1.key, doc2.key);
  219. };
  220. NS_ASSUME_NONNULL_END