/Pods/YapDatabase/YapDatabase/Extensions/Relationships/YapDatabaseRelationshipEdge.m

https://gitlab.com/Mr.Tomato/MeituanDemo · Objective C · 450 lines · 312 code · 106 blank · 32 comment · 71 complexity · 748c6c7bd9c6a782009f40b1981a2ca8 MD5 · raw file

  1. #import "YapDatabaseRelationshipEdge.h"
  2. #import "YapDatabaseRelationshipEdgePrivate.h"
  3. @implementation YapDatabaseRelationshipEdge
  4. @synthesize name = name;
  5. @synthesize sourceCollection = sourceCollection;
  6. @synthesize sourceKey = sourceKey;
  7. @synthesize destinationCollection = destinationCollection;
  8. @synthesize destinationKey = destinationKey;
  9. @synthesize destinationFilePath = destinationFilePath;
  10. @synthesize nodeDeleteRules = nodeDeleteRules;
  11. @synthesize isManualEdge = isManualEdge;
  12. #pragma mark Class Init
  13. + (instancetype)edgeWithName:(NSString *)name
  14. destinationKey:(NSString *)destinationKey
  15. collection:(NSString *)destinationCollection
  16. nodeDeleteRules:(YDB_NodeDeleteRules)rules
  17. {
  18. return [[YapDatabaseRelationshipEdge alloc] initWithName:name
  19. destinationKey:destinationKey
  20. collection:destinationCollection
  21. nodeDeleteRules:rules];
  22. }
  23. + (instancetype)edgeWithName:(NSString *)name
  24. destinationFilePath:(NSString *)destinationFilePath
  25. nodeDeleteRules:(YDB_NodeDeleteRules)rules
  26. {
  27. return [[YapDatabaseRelationshipEdge alloc] initWithName:name
  28. destinationFilePath:destinationFilePath
  29. nodeDeleteRules:rules];
  30. }
  31. + (instancetype)edgeWithName:(NSString *)name
  32. sourceKey:(NSString *)sourceKey
  33. collection:(NSString *)sourceCollection
  34. destinationKey:(NSString *)destinationKey
  35. collection:(NSString *)destinationCollection
  36. nodeDeleteRules:(YDB_NodeDeleteRules)rules
  37. {
  38. return [[YapDatabaseRelationshipEdge alloc] initWithName:name
  39. sourceKey:sourceKey
  40. collection:sourceCollection
  41. destinationKey:destinationKey
  42. collection:destinationCollection
  43. nodeDeleteRules:rules];
  44. }
  45. + (instancetype)edgeWithName:(NSString *)name
  46. sourceKey:(NSString *)sourceKey
  47. collection:(NSString *)sourceCollection
  48. destinationFilePath:(NSString *)destinationFilePath
  49. nodeDeleteRules:(YDB_NodeDeleteRules)rules
  50. {
  51. return [[YapDatabaseRelationshipEdge alloc] initWithName:name
  52. sourceKey:sourceKey
  53. collection:sourceCollection
  54. destinationFilePath:destinationFilePath
  55. nodeDeleteRules:rules];
  56. }
  57. #pragma mark Init
  58. /**
  59. * Public init method.
  60. * Suitable for use with YapDatabaseRelationshipNode protocol.
  61. **/
  62. - (id)initWithName:(NSString *)inName
  63. destinationKey:(NSString *)dstKey
  64. collection:(NSString *)dstCollection
  65. nodeDeleteRules:(YDB_NodeDeleteRules)rules
  66. {
  67. if (inName == nil) return nil; // Edge requires name
  68. if (dstKey == nil) return nil; // Edge requires destination
  69. if ((self = [super init]))
  70. {
  71. name = [inName copy];
  72. destinationKey = [dstKey copy];
  73. destinationCollection = dstCollection ? [dstCollection copy] : @"";
  74. nodeDeleteRules = rules;
  75. isManualEdge = NO;
  76. }
  77. return self;
  78. }
  79. /**
  80. * Public init method.
  81. * Suitable for use with YapDatabaseRelationshipNode protocol.
  82. **/
  83. - (id)initWithName:(NSString *)inName destinationFilePath:(NSString *)dstFilePath
  84. nodeDeleteRules:(YDB_NodeDeleteRules)rules
  85. {
  86. if (inName == nil) return nil; // Edge requires name
  87. if (dstFilePath == nil) return nil; // Edge requires destination
  88. if ((self = [super init]))
  89. {
  90. name = [inName copy];
  91. destinationFilePath = [dstFilePath copy];
  92. nodeDeleteRules = rules;
  93. isManualEdge = NO;
  94. flags = YDB_FlagsHasDestinationRowid; // no need for destinationRowid lookup
  95. }
  96. return self;
  97. }
  98. /**
  99. * Public init method.
  100. * Suitable for use with manual edge management.
  101. **/
  102. - (id)initWithName:(NSString *)inName
  103. sourceKey:(NSString *)srcKey
  104. collection:(NSString *)srcCollection
  105. destinationKey:(NSString *)dstKey
  106. collection:(NSString *)dstCollection
  107. nodeDeleteRules:(YDB_NodeDeleteRules)rules
  108. {
  109. if (inName == nil) return nil; // Edge requires name
  110. if (srcKey == nil) return nil; // Edge requires source
  111. if (dstKey == nil) return nil; // Edge requires destination
  112. if ((self = [super init]))
  113. {
  114. name = [inName copy];
  115. sourceKey = [srcKey copy];
  116. sourceCollection = srcCollection ? [srcCollection copy] : @"";
  117. destinationKey = [dstKey copy];
  118. destinationCollection = dstCollection ? [dstCollection copy] : @"";
  119. nodeDeleteRules = rules;
  120. isManualEdge = YES;
  121. }
  122. return self;
  123. }
  124. - (id)initWithName:(NSString *)inName sourceKey:(NSString *)srcKey
  125. collection:(NSString *)srcCollection
  126. destinationFilePath:(NSString *)dstFilePath
  127. nodeDeleteRules:(YDB_NodeDeleteRules)rules
  128. {
  129. if (inName == nil) return nil; // Edge requires name
  130. if (srcKey == nil) return nil; // Edge requires source
  131. if (dstFilePath == nil) return nil; // Edge requires destination
  132. if ((self = [super init]))
  133. {
  134. name = [inName copy];
  135. sourceKey = [srcKey copy];
  136. sourceCollection = srcCollection ? [srcCollection copy] : @"";
  137. destinationFilePath = [dstFilePath copy];
  138. nodeDeleteRules = rules;
  139. isManualEdge = YES;
  140. flags = YDB_FlagsHasDestinationRowid; // no need for destinationRowid lookup
  141. }
  142. return self;
  143. }
  144. /**
  145. * Internal init method.
  146. * This method is used when reading an edge from a row in the database.
  147. **/
  148. - (id)initWithRowid:(int64_t)rowid
  149. name:(NSString *)inName
  150. src:(int64_t)src
  151. dst:(int64_t)dst
  152. dstFilePath:(NSString *)dstFilePath
  153. rules:(int)rules
  154. manual:(BOOL)manual
  155. {
  156. if ((self = [super init]))
  157. {
  158. name = [inName copy];
  159. destinationFilePath = [dstFilePath copy];
  160. nodeDeleteRules = (unsigned short)rules;
  161. isManualEdge = manual;
  162. edgeRowid = rowid;
  163. sourceRowid = src;
  164. destinationRowid = dst;
  165. flags = YDB_FlagsHasSourceRowid | YDB_FlagsHasDestinationRowid | YDB_FlagsHasEdgeRowid;
  166. }
  167. return self;
  168. }
  169. #pragma mark NSCoding
  170. - (id)initWithCoder:(NSCoder *)decoder
  171. {
  172. if ((self = [super init]))
  173. {
  174. name = [decoder decodeObjectForKey:@"name"];
  175. sourceKey = [decoder decodeObjectForKey:@"sourceKey"];
  176. sourceCollection = [decoder decodeObjectForKey:@"sourceCollection"];
  177. destinationKey = [decoder decodeObjectForKey:@"destinationKey"];
  178. destinationCollection = [decoder decodeObjectForKey:@"destinationCollection"];
  179. destinationFilePath = [decoder decodeObjectForKey:@"destinationFilePath"];
  180. nodeDeleteRules = (unsigned short)[decoder decodeIntForKey:@"nodeDeleteRules"];
  181. isManualEdge = [decoder decodeBoolForKey:@"isManualEdge"];
  182. if (destinationFilePath)
  183. flags = YDB_FlagsHasDestinationRowid;
  184. else
  185. flags = YDB_FlagsNone;
  186. }
  187. return self;
  188. }
  189. - (void)encodeWithCoder:(NSCoder *)coder
  190. {
  191. [coder encodeObject:name forKey:@"name"];
  192. [coder encodeObject:sourceKey forKey:@"sourceKey"];
  193. [coder encodeObject:sourceCollection forKey:@"sourceCollection"];
  194. [coder encodeObject:destinationKey forKey:@"destinationKey"];
  195. [coder encodeObject:destinationCollection forKey:@"destinationCollection"];
  196. [coder encodeObject:destinationFilePath forKey:@"destinationFilePath"];
  197. [coder encodeInt:nodeDeleteRules forKey:@"nodeDeleteRules"];
  198. [coder encodeBool:isManualEdge forKey:@"isManualEdge"];
  199. }
  200. #pragma mark NSCopying
  201. - (id)copyWithZone:(NSZone __unused *)zone
  202. {
  203. YapDatabaseRelationshipEdge *copy = [[YapDatabaseRelationshipEdge alloc] init];
  204. copy->name = name;
  205. copy->sourceKey = sourceKey;
  206. copy->sourceCollection = sourceCollection;
  207. copy->destinationKey = destinationKey;
  208. copy->destinationCollection = destinationCollection;
  209. copy->destinationFilePath = destinationFilePath;
  210. copy->nodeDeleteRules = nodeDeleteRules;
  211. copy->isManualEdge = isManualEdge;
  212. copy->edgeRowid = edgeRowid;
  213. copy->sourceRowid = sourceRowid;
  214. copy->destinationRowid = destinationRowid;
  215. copy->edgeAction = YDB_EdgeActionNone; // Return a clean copy
  216. copy->flags = YDB_FlagsNone; // Return a clean copy
  217. // Set appropriate flags
  218. if ((flags & YDB_FlagsHasSourceRowid))
  219. copy->flags |= YDB_FlagsHasSourceRowid;
  220. if ((flags & YDB_FlagsHasDestinationRowid) || destinationFilePath)
  221. copy->flags |= YDB_FlagsHasDestinationRowid;
  222. if ((flags & YDB_FlagsHasEdgeRowid))
  223. copy->flags |= YDB_FlagsHasEdgeRowid;
  224. return copy;
  225. }
  226. - (id)copyWithSourceKey:(NSString *)newSrcKey collection:(NSString *)newSrcCollection rowid:(int64_t)newSrcRowid
  227. {
  228. YapDatabaseRelationshipEdge *copy = [[YapDatabaseRelationshipEdge alloc] init];
  229. copy->name = name;
  230. copy->sourceKey = [newSrcKey copy];
  231. copy->sourceCollection = [newSrcCollection copy];
  232. copy->destinationKey = destinationKey;
  233. copy->destinationCollection = destinationCollection;
  234. copy->destinationFilePath = destinationFilePath;
  235. copy->nodeDeleteRules = nodeDeleteRules;
  236. copy->isManualEdge = NO; // Force proper value
  237. copy->edgeRowid = edgeRowid;
  238. copy->sourceRowid = newSrcRowid;
  239. copy->destinationRowid = destinationRowid;
  240. copy->edgeAction = YDB_EdgeActionNone; // Return a clean copy
  241. copy->flags = YDB_FlagsNone; // Return a clean copy
  242. // Set appropriate flags
  243. copy->flags |= YDB_FlagsHasSourceRowid;
  244. if ((flags & YDB_FlagsHasDestinationRowid) || destinationFilePath)
  245. copy->flags |= YDB_FlagsHasDestinationRowid;
  246. if ((flags & YDB_FlagsHasEdgeRowid))
  247. copy->flags |= YDB_FlagsHasEdgeRowid;
  248. return copy;
  249. }
  250. #pragma mark Comparison
  251. /**
  252. * Compares two manual edges to see if they represent the same relationship.
  253. * That is, if both edges are manual edges, and the following are equal:
  254. *
  255. * - name
  256. * - sourceKey / sourceCollection
  257. * - destinationKey / destinationCollection
  258. * - destinationFilePath
  259. *
  260. * The nodeDeleteRules do NOT need to match.
  261. **/
  262. - (BOOL)matchesManualEdge:(YapDatabaseRelationshipEdge *)edge
  263. {
  264. if (edge == nil) return NO;
  265. if (!isManualEdge) return NO;
  266. if (!edge->isManualEdge) return NO;
  267. if (![name isEqualToString:edge->name]) return NO;
  268. if (![sourceKey isEqualToString:edge->sourceKey]) return NO;
  269. if (![sourceCollection isEqualToString:edge->sourceCollection]) return NO;
  270. if (destinationFilePath)
  271. {
  272. if (![destinationFilePath isEqualToString:edge->destinationFilePath]) return NO;
  273. }
  274. else
  275. {
  276. if (![destinationKey isEqualToString:edge->destinationKey]) return NO;
  277. if (![destinationCollection isEqualToString:edge->destinationCollection]) return NO;
  278. }
  279. return YES;
  280. }
  281. #pragma mark Description
  282. - (NSString *)description
  283. {
  284. // Create rules string
  285. NSMutableString *rulesStr = [NSMutableString stringWithCapacity:64];
  286. if (nodeDeleteRules & YDB_NotifyIfSourceDeleted)
  287. [rulesStr appendString:@"NotifyIfSourceDeleted, "];
  288. if (nodeDeleteRules & YDB_NotifyIfDestinationDeleted)
  289. [rulesStr appendString:@"NotifyIfDestinationDeleted, "];
  290. if (nodeDeleteRules & YDB_DeleteSourceIfDestinationDeleted)
  291. [rulesStr appendString:@"DeleteSourceIfDestinationDeleted, "];
  292. if (nodeDeleteRules & YDB_DeleteDestinationIfSourceDeleted)
  293. [rulesStr appendString:@"DeleteDestinationIfSourceDeleted, "];
  294. if (nodeDeleteRules & YDB_DeleteSourceIfAllDestinationsDeleted)
  295. [rulesStr appendString:@"DeleteSourceIfAllDestinationsDeleted, "];
  296. if (nodeDeleteRules & YDB_DeleteDestinationIfAllSourcesDeleted)
  297. [rulesStr appendString:@"DeleteDestinationIfAllSourcesDeleted, "];
  298. if ([rulesStr length] > 0)
  299. [rulesStr deleteCharactersInRange:NSMakeRange([rulesStr length] - 2, 2)];
  300. // Create flags description
  301. NSMutableString *flagsStr = [NSMutableString stringWithCapacity:64];
  302. if (flags & YDB_FlagsSourceDeleted)
  303. [flagsStr appendString:@"SourceDeleted, "];
  304. if (flags & YDB_FlagsDestinationDeleted)
  305. [flagsStr appendString:@"DestinationDeleted, "];
  306. if (flags & YDB_FlagsBadSource)
  307. [flagsStr appendString:@"BadSource, "];
  308. if (flags & YDB_FlagsBadDestination)
  309. [flagsStr appendString:@"BadDestination, "];
  310. if (flags & YDB_FlagsHasSourceRowid)
  311. [flagsStr appendString:@"HasSourceRowid, "];
  312. if (flags & YDB_FlagsHasDestinationRowid)
  313. [flagsStr appendString:@"HasDestinationRowid, "];
  314. if (flags & YDB_FlagsHasEdgeRowid)
  315. [flagsStr appendString:@"HasEdgeRowid, "];
  316. if (flags & YDB_FlagsNotInDatabase)
  317. [flagsStr appendString:@"NotInDatabase, "];
  318. if ([flagsStr length] > 0)
  319. [flagsStr deleteCharactersInRange:NSMakeRange([flagsStr length] - 2, 2)];
  320. // Create edge description
  321. NSMutableString *description = [NSMutableString stringWithCapacity:128];
  322. [description appendFormat:@"<YapDatabaseRelationshipEdge[%p]", self];
  323. [description appendFormat:@" name(%@)", name];
  324. if (sourceKey)
  325. [description appendFormat:@" src(%@, %@)", sourceKey, (sourceCollection ?: @"")];
  326. else if (flags & YDB_FlagsHasSourceRowid)
  327. [description appendFormat:@" srcRowid(%lld)", sourceRowid];
  328. if (destinationKey)
  329. [description appendFormat:@" dst(%@, %@)", destinationKey, (destinationCollection ?: @"")];
  330. else if (destinationFilePath)
  331. [description appendFormat:@" dstFilePath(%@)", destinationFilePath];
  332. else if (flags & YDB_FlagsHasDestinationRowid)
  333. [description appendFormat:@" dstRowid(%lld)", destinationRowid];
  334. [description appendFormat:@" rules(%@)", rulesStr];
  335. if ([flagsStr length] > 0) {
  336. [description appendFormat:@" flags(%@)", flagsStr];
  337. }
  338. if (isManualEdge) {
  339. [description appendString:@" manual"];
  340. }
  341. [description appendString:@">"];
  342. return description;
  343. }
  344. @end