FEMManagedObjectCache.m 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // For License please refer to LICENSE file in the root of FastEasyMapping project
  2. #import "FEMManagedObjectCache.h"
  3. #import <CoreData/CoreData.h>
  4. #import "FEMMapping.h"
  5. #import "FEMRepresentationUtility.h"
  6. @implementation FEMManagedObjectCache {
  7. NSManagedObjectContext *_context;
  8. NSDictionary *_lookupKeysMap;
  9. NSMutableDictionary *_lookupObjectsMap;
  10. }
  11. #pragma mark - Init
  12. - (instancetype)initWithMapping:(FEMMapping *)mapping representation:(id)representation context:(NSManagedObjectContext *)context {
  13. NSParameterAssert(mapping);
  14. NSParameterAssert(representation);
  15. NSParameterAssert(context);
  16. self = [self init];
  17. if (self) {
  18. _context = context;
  19. _lookupKeysMap = FEMRepresentationCollectPresentedPrimaryKeys(representation, mapping);
  20. _lookupObjectsMap = [NSMutableDictionary new];
  21. }
  22. return self;
  23. }
  24. #pragma mark - Inspection
  25. - (NSMutableDictionary *)fetchExistingObjectsForMapping:(FEMMapping *)mapping {
  26. NSSet *lookupValues = _lookupKeysMap[mapping.entityName];
  27. if (lookupValues.count == 0) return [NSMutableDictionary dictionary];
  28. NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:mapping.entityName];
  29. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K IN %@", mapping.primaryKey, lookupValues];
  30. [fetchRequest setPredicate:predicate];
  31. [fetchRequest setFetchLimit:lookupValues.count];
  32. NSMutableDictionary *output = [NSMutableDictionary new];
  33. NSArray *existingObjects = [_context executeFetchRequest:fetchRequest error:NULL];
  34. for (NSManagedObject *object in existingObjects) {
  35. output[[object valueForKey:mapping.primaryKey]] = object;
  36. }
  37. return output;
  38. }
  39. - (NSMutableDictionary *)cachedObjectsForMapping:(FEMMapping *)mapping {
  40. NSMutableDictionary *entityObjectsMap = _lookupObjectsMap[mapping.entityName];
  41. if (!entityObjectsMap) {
  42. entityObjectsMap = [self fetchExistingObjectsForMapping:mapping];
  43. _lookupObjectsMap[mapping.entityName] = entityObjectsMap;
  44. }
  45. return entityObjectsMap;
  46. }
  47. - (id)existingObjectForRepresentation:(id)representation mapping:(FEMMapping *)mapping {
  48. NSDictionary *entityObjectsMap = [self cachedObjectsForMapping:mapping];
  49. id primaryKeyValue = FEMRepresentationValueForAttribute(representation, mapping.primaryKeyAttribute);
  50. if (primaryKeyValue == nil || primaryKeyValue == NSNull.null) return nil;
  51. return entityObjectsMap[primaryKeyValue];
  52. }
  53. - (id)existingObjectForPrimaryKey:(id)primaryKey mapping:(FEMMapping *)mapping {
  54. NSDictionary *entityObjectsMap = [self cachedObjectsForMapping:mapping];
  55. return entityObjectsMap[primaryKey];
  56. }
  57. - (void)addExistingObject:(id)object mapping:(FEMMapping *)mapping {
  58. NSParameterAssert(mapping.primaryKey);
  59. NSParameterAssert(object);
  60. id primaryKeyValue = [object valueForKey:mapping.primaryKey];
  61. NSAssert(primaryKeyValue, @"No value for key (%@) on object (%@) found", mapping.primaryKey, object);
  62. NSMutableDictionary *entityObjectsMap = [self cachedObjectsForMapping:mapping];
  63. entityObjectsMap[primaryKeyValue] = object;
  64. }
  65. - (NSDictionary *)existingObjectsForMapping:(FEMMapping *)mapping {
  66. return [[self cachedObjectsForMapping:mapping] copy];
  67. }
  68. @end