Skip to content

Commit

Permalink
Merge branch 'release/0.20.0-pre6'
Browse files Browse the repository at this point in the history
  • Loading branch information
blakewatters committed Jan 4, 2013
2 parents 9103b9b + ee00e59 commit 22dd9ab
Show file tree
Hide file tree
Showing 71 changed files with 2,105 additions and 723 deletions.
4 changes: 2 additions & 2 deletions Code/CoreData/RKConnectionDescription.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
@param sourceToDestinationEntityAttributes A dictionary specifying how attributes on the source entity correspond to attributes on the destination entity.
@return The receiver, initialized with the given relationship and attributes.
*/
- (instancetype)initWithRelationship:(NSRelationshipDescription *)relationship attributes:(NSDictionary *)sourceToDestinationEntityAttributes;
- (id)initWithRelationship:(NSRelationshipDescription *)relationship attributes:(NSDictionary *)sourceToDestinationEntityAttributes;

/**
The dictionary of attributes specifying how attributes on the source entity for the relationship correspond to attributes on the destination entity.
Expand All @@ -115,7 +115,7 @@
@param keyPath The key path from which to read the value that is to be set for the relationship.
@return The receiver, initialized with the given relationship and key path.
*/
- (instancetype)initWithRelationship:(NSRelationshipDescription *)relationship keyPath:(NSString *)keyPath;
- (id)initWithRelationship:(NSRelationshipDescription *)relationship keyPath:(NSString *)keyPath;

/**
The key path that is to be evaluated to obtain the value for the relationship.
Expand Down
4 changes: 2 additions & 2 deletions Code/CoreData/RKConnectionDescription.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ @interface RKConnectionDescription ()

@implementation RKConnectionDescription

- (instancetype)initWithRelationship:(NSRelationshipDescription *)relationship attributes:(NSDictionary *)attributes
- (id)initWithRelationship:(NSRelationshipDescription *)relationship attributes:(NSDictionary *)attributes
{
NSParameterAssert(relationship);
NSParameterAssert(attributes);
Expand All @@ -63,7 +63,7 @@ - (instancetype)initWithRelationship:(NSRelationshipDescription *)relationship a
return self;
}

- (instancetype)initWithRelationship:(NSRelationshipDescription *)relationship keyPath:(NSString *)keyPath
- (id)initWithRelationship:(NSRelationshipDescription *)relationship keyPath:(NSString *)keyPath
{
NSParameterAssert(relationship);
NSParameterAssert(keyPath);
Expand Down
2 changes: 1 addition & 1 deletion Code/CoreData/RKEntityByAttributeCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
@return The receiver, initialized with the given entity, attribute, and managed object
context.
*/
- (instancetype)initWithEntity:(NSEntityDescription *)entity attributes:(NSArray *)attributeNames managedObjectContext:(NSManagedObjectContext *)context;
- (id)initWithEntity:(NSEntityDescription *)entity attributes:(NSArray *)attributeNames managedObjectContext:(NSManagedObjectContext *)context;

///-----------------------------
/// @name Getting Cache Identity
Expand Down
2 changes: 1 addition & 1 deletion Code/CoreData/RKEntityCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
@param context The managed object context containing objects to be cached.
@returns self, initialized with context.
*/
- (instancetype)initWithManagedObjectContext:(NSManagedObjectContext *)context;
- (id)initWithManagedObjectContext:(NSManagedObjectContext *)context;

/**
The managed object context with which the receiver is associated.
Expand Down
13 changes: 12 additions & 1 deletion Code/CoreData/RKEntityMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
@param entity An entity with which to initialize the receiver.
@returns The receiver, initialized with the given entity.
*/
- (instancetype)initWithEntity:(NSEntityDescription *)entity;
- (id)initWithEntity:(NSEntityDescription *)entity;

/**
A convenience initializer that creates and returns an entity mapping for the entity with the given name in
Expand Down Expand Up @@ -177,6 +177,17 @@
*/
- (RKConnectionDescription *)connectionForRelationship:(id)relationshipOrName;

///------------------------------------
/// @name Flagging Objects for Deletion
///------------------------------------

/**
A predicate that identifies objects for the receiver's entity that are to be deleted from the local store.
This property provides support for local deletion of managed objects mapped as a 'tombstone' record from the source representation.
*/
@property (nonatomic, copy) NSPredicate *deletionPredicate;

///------------------------------------------
/// @name Retrieving Default Attribute Values
///------------------------------------------
Expand Down
6 changes: 3 additions & 3 deletions Code/CoreData/RKEntityMapping.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#import "RKEntityMapping.h"
#import "RKManagedObjectStore.h"
#import "RKDynamicMappingMatcher.h"
#import "RKObjectMappingMatcher.h"
#import "RKPropertyInspector+CoreData.h"
#import "RKLog.h"
#import "RKRelationshipMapping.h"
Expand Down Expand Up @@ -153,7 +153,7 @@ + (instancetype)mappingForEntityForName:(NSString *)entityName inManagedObjectSt
return [[self alloc] initWithEntity:entity];
}

- (instancetype)initWithEntity:(NSEntityDescription *)entity
- (id)initWithEntity:(NSEntityDescription *)entity
{
NSAssert(entity, @"Cannot initialize an RKEntityMapping without an entity. Maybe you want RKObjectMapping instead?");
Class objectClass = NSClassFromString([entity managedObjectClassName]);
Expand All @@ -167,7 +167,7 @@ - (instancetype)initWithEntity:(NSEntityDescription *)entity
return self;
}

- (instancetype)initWithClass:(Class)objectClass
- (id)initWithClass:(Class)objectClass
{
self = [super initWithClass:objectClass];
if (self) {
Expand Down
2 changes: 1 addition & 1 deletion Code/CoreData/RKInMemoryManagedObjectCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@
@param managedObjectContext The managed object context with which to initialize the receiver.
@return The receiver, initialized with the given managed object context.
*/
- (instancetype)initWithManagedObjectContext:(NSManagedObjectContext *)managedObjectContext;
- (id)initWithManagedObjectContext:(NSManagedObjectContext *)managedObjectContext;

@end
4 changes: 2 additions & 2 deletions Code/CoreData/RKManagedObjectImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
@warning As this initialization code path is typical for generating seed databases, the value of
`resetsStoreBeforeImporting` is initialized to **YES**.
*/
- (instancetype)initWithManagedObjectModel:(NSManagedObjectModel *)managedObjectModel storePath:(NSString *)storePath;
- (id)initWithManagedObjectModel:(NSManagedObjectModel *)managedObjectModel storePath:(NSString *)storePath;

/**
Initializes the receiver with a given persistent store in which to persist imported managed objects.
Expand All @@ -69,7 +69,7 @@
managed object model are determined from the given persistent store and a new managed object context with
the private queue concurrency type is constructed.
*/
- (instancetype)initWithPersistentStore:(NSPersistentStore *)persistentStore;
- (id)initWithPersistentStore:(NSPersistentStore *)persistentStore;

/**
A Boolean value indicating whether existing managed objects in the persistent store should
Expand Down
2 changes: 1 addition & 1 deletion Code/CoreData/RKManagedObjectMappingOperationDataSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
@param managedObjectCache The managed object cache used by the receiver to find existing object instances by their identification attributes.
@return The receiver, initialized with the given managed object context and managed objet cache.
*/
- (instancetype)initWithManagedObjectContext:(NSManagedObjectContext *)managedObjectContext cache:(id<RKManagedObjectCaching>)managedObjectCache;
- (id)initWithManagedObjectContext:(NSManagedObjectContext *)managedObjectContext cache:(id<RKManagedObjectCaching>)managedObjectCache;

///-----------------------------------------------------
/// @name Accessing the Managed Object Context and Cache
Expand Down
97 changes: 92 additions & 5 deletions Code/CoreData/RKManagedObjectMappingOperationDataSource.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,26 @@
// limitations under the License.
//

#import <objc/runtime.h>
#import "RKManagedObjectMappingOperationDataSource.h"
#import "RKObjectMapping.h"
#import "RKEntityMapping.h"
#import "RKLog.h"
#import "RKManagedObjectStore.h"
#import "RKMappingOperation.h"
#import "RKDynamicMappingMatcher.h"
#import "RKObjectMappingMatcher.h"
#import "RKManagedObjectCaching.h"
#import "RKRelationshipConnectionOperation.h"
#import "RKMappingErrors.h"
#import "RKValueTransformers.h"
#import "RKRelationshipMapping.h"
#import "RKObjectUtilities.h"
#import "NSManagedObject+RKAdditions.h"

extern NSString * const RKObjectMappingNestingAttributeKeyName;

static char kRKManagedObjectMappingOperationDataSourceAssociatedObjectKey;

id RKTransformedValueWithClass(id value, Class destinationType, NSValueTransformer *dateToStringValueTransformer);
NSArray *RKApplyNestingAttributeValueToMappings(NSString *attributeName, id value, NSArray *propertyMappings);

Expand Down Expand Up @@ -117,6 +121,58 @@ static id RKValueForAttributeMappingInRepresentation(RKAttributeMapping *attribu
return entityIdentifierAttributes;
}

@interface RKManagedObjectDeletionOperation : NSOperation

- (id)initWithManagedObjectContext:(NSManagedObjectContext *)managedObjectContext;
- (void)addEntityMapping:(RKEntityMapping *)entityMapping;
@end

@interface RKManagedObjectDeletionOperation ()
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) NSMutableSet *entityMappings;
@end

@implementation RKManagedObjectDeletionOperation

- (id)initWithManagedObjectContext:(NSManagedObjectContext *)managedObjectContext
{
self = [self init];
if (self) {
self.managedObjectContext = managedObjectContext;
self.entityMappings = [NSMutableSet new];
}
return self;
}

- (void)addEntityMapping:(RKEntityMapping *)entityMapping
{
if (! entityMapping.deletionPredicate) return;
[self.entityMappings addObject:entityMapping];
}

- (void)main
{
[self.managedObjectContext performBlockAndWait:^{
NSMutableSet *objectsToDelete = [NSMutableSet set];
for (RKEntityMapping *entityMapping in self.entityMappings) {
NSFetchRequest *fetchRequest = [NSFetchRequest alloc];
[fetchRequest setEntity:entityMapping.entity];
[fetchRequest setPredicate:entityMapping.deletionPredicate];
NSError *error = nil;
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects) {
[objectsToDelete addObjectsFromArray:fetchedObjects];
}
}

for (NSManagedObject *managedObject in objectsToDelete) {
[self.managedObjectContext deleteObject:managedObject];
}
}];
}

@end

// Set Logging Component
#undef RKLogComponent
#define RKLogComponent RKlcl_cRestKitCoreData
Expand All @@ -126,11 +182,12 @@ static id RKValueForAttributeMappingInRepresentation(RKAttributeMapping *attribu
@interface RKManagedObjectMappingOperationDataSource ()
@property (nonatomic, strong, readwrite) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong, readwrite) id<RKManagedObjectCaching> managedObjectCache;
@property (nonatomic, strong) NSMutableArray *deletionPredicates;
@end

@implementation RKManagedObjectMappingOperationDataSource

- (instancetype)initWithManagedObjectContext:(NSManagedObjectContext *)managedObjectContext cache:(id<RKManagedObjectCaching>)managedObjectCache
- (id)initWithManagedObjectContext:(NSManagedObjectContext *)managedObjectContext cache:(id<RKManagedObjectCaching>)managedObjectCache
{
NSParameterAssert(managedObjectContext);

Expand Down Expand Up @@ -169,7 +226,7 @@ - (id)mappingOperation:(RKMappingOperation *)mappingOperation targetObjectForRep
"Unable to update existing object instances by identification attributes. Duplicate objects may be created.");
}

// If we have found the entity identifier attributes, try to find an existing instance to update
// If we have found the entity identification attributes, try to find an existing instance to update
NSEntityDescription *entity = [entityMapping entity];
NSManagedObject *managedObject = nil;
if ([entityIdentifierAttributes count]) {
Expand All @@ -187,8 +244,7 @@ - (id)mappingOperation:(RKMappingOperation *)mappingOperation targetObjectForRep
}

if (managedObject == nil) {
managedObject = [[NSManagedObject alloc] initWithEntity:entity
insertIntoManagedObjectContext:self.managedObjectContext];
managedObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext];
[managedObject setValuesForKeysWithDictionary:entityIdentifierAttributes];

if ([self.managedObjectCache respondsToSelector:@selector(didCreateObject:)]) {
Expand Down Expand Up @@ -220,6 +276,16 @@ - (BOOL)commitChangesForMappingOperation:(RKMappingOperation *)mappingOperation
if ([mappingOperation.objectMapping isKindOfClass:[RKEntityMapping class]]) {
[self emitDeadlockWarningIfNecessary];

// Validate unsaved objects
if ([mappingOperation.destinationObject isKindOfClass:[NSManagedObject class]] && [(NSManagedObject *)mappingOperation.destinationObject isNew]) {
NSError *validationError = nil;
if (! [(NSManagedObject *)mappingOperation.destinationObject validateForInsert:&validationError]) {
RKLogDebug(@"Unsaved NSManagedObject failed `validateForInsert:` - Deleting object from context: %@", validationError);
[self.managedObjectContext deleteObject:mappingOperation.destinationObject];
return YES;
}
}

NSArray *connections = [(RKEntityMapping *)mappingOperation.objectMapping connections];
if ([connections count] > 0 && self.managedObjectCache == nil) {
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: @"Cannot map an entity mapping that contains connection mappings with a data source whose managed object cache is nil." };
Expand All @@ -246,6 +312,27 @@ - (BOOL)commitChangesForMappingOperation:(RKMappingOperation *)mappingOperation
[operationQueue addOperation:operation];
RKLogTrace(@"Enqueued %@ dependent upon parent operation %@ to operation queue %@", operation, self.parentOperation, operationQueue);
}

// Handle tombstone deletion by predicate
if ([(RKEntityMapping *)mappingOperation.objectMapping deletionPredicate]) {
RKManagedObjectDeletionOperation *deletionOperation = nil;
if (self.parentOperation) {
// Attach a deletion operation for execution after the parent operation completes
deletionOperation = (RKManagedObjectDeletionOperation *)objc_getAssociatedObject(self.parentOperation, &kRKManagedObjectMappingOperationDataSourceAssociatedObjectKey);
if (! deletionOperation) {
deletionOperation = [[RKManagedObjectDeletionOperation alloc] initWithManagedObjectContext:self.managedObjectContext];
objc_setAssociatedObject(self.parentOperation, &kRKManagedObjectMappingOperationDataSourceAssociatedObjectKey, deletionOperation, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[deletionOperation addDependency:self.parentOperation];
NSOperationQueue *operationQueue = self.operationQueue ?: [NSOperationQueue currentQueue];
[operationQueue addOperation:deletionOperation];
}
[deletionOperation addEntityMapping:(RKEntityMapping *)mappingOperation.objectMapping];
} else {
deletionOperation = [[RKManagedObjectDeletionOperation alloc] initWithManagedObjectContext:self.managedObjectContext];
[deletionOperation addEntityMapping:(RKEntityMapping *)mappingOperation.objectMapping];
[deletionOperation start];
}
}
}

return YES;
Expand Down
6 changes: 3 additions & 3 deletions Code/CoreData/RKManagedObjectStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
*/
- (instancetype)initWithManagedObjectModel:(NSManagedObjectModel *)managedObjectModel;
- (id)initWithManagedObjectModel:(NSManagedObjectModel *)managedObjectModel;

/**
Initializes the receiver with an existing persistent store coordinator.
Expand All @@ -88,7 +88,7 @@
@param persistentStoreCoordinator The persistent store coordinator with which to initialize the receiver.
@return The receiver, initialized with the managed object model of the given persistent store coordinator and the persistent store coordinator.
*/
- (instancetype)initWithPersistentStoreCoordinator:(NSPersistentStoreCoordinator *)persistentStoreCoordinator;
- (id)initWithPersistentStoreCoordinator:(NSPersistentStoreCoordinator *)persistentStoreCoordinator;

/**
Initializes the receiver with a managed object model obtained by merging the models from all of the application's non-framework bundles.
Expand All @@ -98,7 +98,7 @@
@warning Obtaining a managed object model by merging all bundles may result in an application error if versioned object models are in use.
*/
- (instancetype)init;
- (id)init;

///-----------------------------------------------------------------------------
/// @name Configuring Persistent Stores
Expand Down
4 changes: 2 additions & 2 deletions Code/CoreData/RKManagedObjectStore.m
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ + (void)setDefaultStore:(RKManagedObjectStore *)managedObjectStore
}
}

- (instancetype)initWithManagedObjectModel:(NSManagedObjectModel *)managedObjectModel
- (id)initWithManagedObjectModel:(NSManagedObjectModel *)managedObjectModel
{
self = [super init];
if (self) {
Expand All @@ -73,7 +73,7 @@ - (instancetype)initWithManagedObjectModel:(NSManagedObjectModel *)managedObject
return self;
}

- (instancetype)initWithPersistentStoreCoordinator:(NSPersistentStoreCoordinator *)persistentStoreCoordinator
- (id)initWithPersistentStoreCoordinator:(NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
self = [self initWithManagedObjectModel:persistentStoreCoordinator.managedObjectModel];
if (self) {
Expand Down
2 changes: 1 addition & 1 deletion Code/CoreData/RKRelationshipConnectionOperation.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
@param managedObjectCache The managed object cache from which to attempt to fetch a matching object to satisfy the connection.
@return The receiver, initialized with the given managed object, connection mapping, and managed object cache.
*/
- (instancetype)initWithManagedObject:(NSManagedObject *)managedObject
- (id)initWithManagedObject:(NSManagedObject *)managedObject
connection:(RKConnectionDescription *)connection
managedObjectCache:(id<RKManagedObjectCaching>)managedObjectCache;

Expand Down
4 changes: 2 additions & 2 deletions Code/CoreData/RKRelationshipConnectionOperation.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#import "RKEntityMapping.h"
#import "RKLog.h"
#import "RKManagedObjectCaching.h"
#import "RKDynamicMappingMatcher.h"
#import "RKObjectMappingMatcher.h"
#import "RKErrors.h"
#import "RKObjectUtilities.h"

Expand Down Expand Up @@ -70,7 +70,7 @@ @interface RKRelationshipConnectionOperation ()

@implementation RKRelationshipConnectionOperation

- (instancetype)initWithManagedObject:(NSManagedObject *)managedObject
- (id)initWithManagedObject:(NSManagedObject *)managedObject
connection:(RKConnectionDescription *)connection
managedObjectCache:(id<RKManagedObjectCaching>)managedObjectCache;
{
Expand Down
Loading

0 comments on commit 22dd9ab

Please sign in to comment.