Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

More robust deletion of SQLite stores

- Core Data makes other supplementary files in addition to the .sqlite file, so deleting those as well for good measure.
- Previously, we had this Core Data deletion implementation in our app code and then MagicalRecord used another Core Data deletion implementation.  It’s best if everyone can use one Core Data deletion implementation.  As a result, making this a public method on NSPersistentStore so that everyone has access to it.
  • Loading branch information...
commit a7bfaa9931519b3933f699d14970697bfa9632fc 1 parent 5568b3f
@bachand bachand authored
View
2  MagicalRecord/Categories/NSPersistentStore+MagicalRecord.h
@@ -22,6 +22,8 @@ extern NSString * const kMagicalRecordDefaultStoreFileName;
+ (NSURL *) MR_urlForStoreName:(NSString *)storeFileName;
+ (NSURL *) MR_cloudURLForUbiqutiousContainer:(NSString *)bucketName;
++ (BOOL)MR_deleteFilesForSqliteStoreAtURL:(NSURL *)sqliteStoreURL withFileManager:(NSFileManager *)manager;
+
@end
View
51 MagicalRecord/Categories/NSPersistentStore+MagicalRecord.m
@@ -76,4 +76,55 @@ + (NSURL *) MR_defaultLocalStoreUrl
return [self MR_urlForStoreName:kMagicalRecordDefaultStoreFileName];
}
++ (BOOL)MR_deleteFilesForSqliteStoreAtURL:(NSURL *)sqliteStoreURL withFileManager:(NSFileManager *)manager
+{
+ if (![[sqliteStoreURL pathExtension] isEqualToString:@"sqlite"]) {
+ NSString *reason = [NSString stringWithFormat:@"*** -[%@ %@]: sqliteStoreURL does not point to a .sqlite file",
+ NSStringFromClass([self class]),
+ NSStringFromSelector(_cmd)];
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil];
+ }
+
+ NSString *storeDirectoryPath = [[sqliteStoreURL path] stringByDeletingLastPathComponent];
+ NSString *storeFilename = [[sqliteStoreURL path] lastPathComponent];
+
+ NSError *fileError;
+ NSArray *storeDirectoryContents;
+ storeDirectoryContents = [manager contentsOfDirectoryAtPath:storeDirectoryPath error:&fileError];
+
+ BOOL result = YES;
+ if (fileError) {
+ [MagicalRecord handleErrors:fileError];
+ result = NO;
+ } else {
+ NSError *regexError;
+ NSString *pattern = [NSString stringWithFormat:@"\\A%@.*\\z", storeFilename];
+ NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
+ options:kNilOptions
+ error:&regexError];
+ if (regexError) {
+ [MagicalRecord handleErrors:regexError];
+ result = NO;
+ } else {
+ for (NSString *filename in storeDirectoryContents) {
+ NSRange filenameRange = NSMakeRange(0, [filename length]);
+ NSUInteger numMatches = [regex numberOfMatchesInString:filename
+ options:kNilOptions
+ range:filenameRange];
+ if (numMatches > 0) {
+ NSString *fullFilePath = [storeDirectoryPath stringByAppendingPathComponent:filename];
+ NSError *deletionError;
+ if ([manager removeItemAtPath:fullFilePath error:&deletionError]) {
+ MRLogInfo(@"Removed SQLite persistent store file at path '%@'", fullFilePath);
+ } else {
+ [MagicalRecord handleErrors:deletionError];
+ result = NO;
+ }
+ }
+ }
+ }
+ }
+ return result;
+}
+
@end
View
14 MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m
@@ -81,10 +81,18 @@ - (NSPersistentStore *) MR_addSqliteStoreNamed:(id)storeFileName withOptions:(__
if ([[error domain] isEqualToString:NSCocoaErrorDomain] && isMigrationError)
{
// Could not open the database, so... kill it!
- [[NSFileManager defaultManager] removeItemAtURL:url error:nil];
-
- MRLogInfo(@"Removed incompatible model version: %@", [url lastPathComponent]);
+ NSFileManager *manager = [NSFileManager defaultManager];
+ BOOL deletionResult = [NSPersistentStore MR_deleteFilesForSqliteStoreAtURL:url
+ withFileManager:manager];
+ if (deletionResult) {
+ MRLogInfo(@"Removed SQLite store %@ to resolve incompatible model version",
+ [url lastPathComponent]);
+ } else {
+ MRLogWarn(@"Unable to fully remove SQLite store %@ to resolve incompatible model version; will try to create store one more time anyway",
+ [url lastPathComponent]);
+ }
+
// Try one more time to create the store
store = [self addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
Please sign in to comment.
Something went wrong with that request. Please try again.