From b8326a667d0ec79556af6accb0325fd31ea62010 Mon Sep 17 00:00:00 2001 From: Stephen Vanterpool Date: Sun, 19 Aug 2012 22:55:48 -0700 Subject: [PATCH 1/5] Added automatic store deletion if the store does not match the model --- ...PersistentStoreCoordinator+MagicalRecord.m | 29 +++++++++++++++---- MagicalRecord/Core/MagicalRecord+Options.h | 8 +++++ MagicalRecord/Core/MagicalRecord+Options.m | 11 +++++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m b/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m index 5c5f56b..48e2207 100644 --- a/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m +++ b/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m @@ -70,12 +70,31 @@ NSString * const kMagicalRecordPSCDidCompleteiCloudSetupNotification = @"kMagica [self MR_createPathToStoreFileIfNeccessary:url]; NSPersistentStore *store = [self addPersistentStoreWithType:NSSQLiteStoreType - configuration:nil - URL:url - options:options - error:&error]; - if (!store) + configuration:nil + URL:url + options:options + error:&error]; + + if (!store && [MagicalRecord shouldDeleteStoreOnModelMismatch]) { + if ([error.domain isEqualToString:NSCocoaErrorDomain] && + [error code] == NSMigrationMissingSourceModelError) { + // Could not open the database, so... kill it! + [[NSFileManager defaultManager] removeItemAtURL:url error:nil]; + + // Try one more time to create the store + store = [self addPersistentStoreWithType:NSSQLiteStoreType + configuration:nil + URL:url + options:options + error:&error]; + if (store) { + // If we successfully added a store, remove the error that was initially created + error = nil; + } + } + + [MagicalRecord handleErrors:error]; } return store; diff --git a/MagicalRecord/Core/MagicalRecord+Options.h b/MagicalRecord/Core/MagicalRecord+Options.h index e0d224e..72012c7 100644 --- a/MagicalRecord/Core/MagicalRecord+Options.h +++ b/MagicalRecord/Core/MagicalRecord+Options.h @@ -20,6 +20,14 @@ + (void) setShouldAutoCreateManagedObjectModel:(BOOL)shouldAutoCreate; + (BOOL) shouldAutoCreateDefaultPersistentStoreCoordinator; + (void) setShouldAutoCreateDefaultPersistentStoreCoordinator:(BOOL)shouldAutoCreate; ++ (void) setShouldDeleteStoreOnModelMismatch:(BOOL)shouldDeleteStoreOnModelMismatch; + +/*! + @method shouldDeleteStoreOnModelMistmatch + @abstract If true, when configuring the persistant store coordinator, and Magical Record encounters a store that does not match the model, it will attempt to remove it and re-create a new store. + This is extremely useful during development where every model change could potentially require a delete/reinstall of the app. + */ ++ (BOOL) shouldDeleteStoreOnModelMismatch; @end diff --git a/MagicalRecord/Core/MagicalRecord+Options.m b/MagicalRecord/Core/MagicalRecord+Options.m index eb48c80..a076558 100644 --- a/MagicalRecord/Core/MagicalRecord+Options.m +++ b/MagicalRecord/Core/MagicalRecord+Options.m @@ -10,6 +10,7 @@ static BOOL shouldAutoCreateManagedObjectModel_; static BOOL shouldAutoCreateDefaultPersistentStoreCoordinator_; +static BOOL shouldDeleteStoreOnModelMismatch_; @implementation MagicalRecord (Options) @@ -35,4 +36,14 @@ static BOOL shouldAutoCreateDefaultPersistentStoreCoordinator_; shouldAutoCreateDefaultPersistentStoreCoordinator_ = shouldAutoCreate; } ++ (BOOL) shouldDeleteStoreOnModelMismatch; +{ + return shouldDeleteStoreOnModelMismatch_; +} + ++ (void) setShouldDeleteStoreOnModelMismatch:(BOOL)shouldDeleteStoreOnModelMismatch +{ + shouldDeleteStoreOnModelMismatch_ = shouldDeleteStoreOnModelMismatch; +} + @end From 22fe81a224cf48600fa3bbdd26a6fb0e3954bfe7 Mon Sep 17 00:00:00 2001 From: Stephen Vanterpool Date: Sun, 19 Aug 2012 22:56:14 -0700 Subject: [PATCH 2/5] Missed the configuration --- MagicalRecord/Core/MagicalRecord.m | 1 + 1 file changed, 1 insertion(+) diff --git a/MagicalRecord/Core/MagicalRecord.m b/MagicalRecord/Core/MagicalRecord.m index 7be05e0..f9ffbd7 100644 --- a/MagicalRecord/Core/MagicalRecord.m +++ b/MagicalRecord/Core/MagicalRecord.m @@ -91,6 +91,7 @@ void reset_action_queue(void); #endif [self setShouldAutoCreateManagedObjectModel:YES]; [self setShouldAutoCreateDefaultPersistentStoreCoordinator:NO]; + [self setShouldDeleteStoreOnModelMismatch:YES]; } } From d8394cfdabea14332d4a5dc7d86ebec4b6a43d8f Mon Sep 17 00:00:00 2001 From: Stephen Vanterpool Date: Sun, 19 Aug 2012 23:24:36 -0700 Subject: [PATCH 3/5] Updating readme with a short blurb --- .../Categories/NSPersistentStoreCoordinator+MagicalRecord.m | 3 +-- README.md | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m b/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m index 48e2207..66b8da7 100644 --- a/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m +++ b/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m @@ -93,8 +93,7 @@ NSString * const kMagicalRecordPSCDidCompleteiCloudSetupNotification = @"kMagica error = nil; } } - - + [MagicalRecord handleErrors:error]; } return store; diff --git a/README.md b/README.md index 29cb93a..d3eb787 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,9 @@ Next, somewhere in your app delegate, in either the applicationDidFinishLaunchin Each call instantiates one of each piece of the Core Data stack, and provides getter and setter methods for these instances. These well known instances to MagicalRecord, and are recognized as "defaults". -And, before your app exits, you can use the clean up method: +When using the default sqlite data store, if you change your model without creating a new model version, Magical Record will delete the old store and create a new one automatically. No more uninstall/reinstall every time you make a change! + +And finally, before your app exits, you can use the clean up method: [MagicalRecord cleanUp]; From 45d764a58d4b11c0cbdeb10fa442a18680e492ff Mon Sep 17 00:00:00 2001 From: Stephen Vanterpool Date: Sun, 19 Aug 2012 23:37:37 -0700 Subject: [PATCH 4/5] Cleanup code is now debug-only --- MagicalRecord/Core/MagicalRecord.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MagicalRecord/Core/MagicalRecord.m b/MagicalRecord/Core/MagicalRecord.m index f9ffbd7..658b6cd 100644 --- a/MagicalRecord/Core/MagicalRecord.m +++ b/MagicalRecord/Core/MagicalRecord.m @@ -91,7 +91,11 @@ void reset_action_queue(void); #endif [self setShouldAutoCreateManagedObjectModel:YES]; [self setShouldAutoCreateDefaultPersistentStoreCoordinator:NO]; +#ifdef DEBUG [self setShouldDeleteStoreOnModelMismatch:YES]; +#else + [self setShouldDeleteStoreOnModelMismatch:NO]; +#endif } } From 8842d8f7bb23175ae6df211bfefe04f9ae351276 Mon Sep 17 00:00:00 2001 From: Stephen Vanterpool Date: Mon, 20 Aug 2012 10:52:19 -0700 Subject: [PATCH 5/5] Clarified the DEBUG only nature of the fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d3eb787..4c42c0d 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ Next, somewhere in your app delegate, in either the applicationDidFinishLaunchin Each call instantiates one of each piece of the Core Data stack, and provides getter and setter methods for these instances. These well known instances to MagicalRecord, and are recognized as "defaults". -When using the default sqlite data store, if you change your model without creating a new model version, Magical Record will delete the old store and create a new one automatically. No more uninstall/reinstall every time you make a change! +When using the default sqlite data store with the DEBUG flag set, if you change your model without creating a new model version, Magical Record will delete the old store and create a new one automatically. No more uninstall/reinstall every time you make a change! And finally, before your app exits, you can use the clean up method: