2
0

More robust migration.

[FIXED]     Better recovery from failure to migrate local store.
[FIXED]     Ability to migrate outdated local store models.
This commit is contained in:
Maarten Billemont 2013-08-31 12:29:56 -04:00
parent 34645c9433
commit ab360066e5
2 changed files with 38 additions and 22 deletions

@ -1 +1 @@
Subproject commit 6d31bad83824aab9840c3812807aaffc7e0eb5fd Subproject commit 77327f4adc7ca9dbca1a1f3e632d1e95c9ce7e56

View File

@ -142,7 +142,10 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
inf(@"Local store migration level: %d (current %d)", (signed)migrationLevel, (signed)MPMigrationLevelLocalStoreCurrent); inf(@"Local store migration level: %d (current %d)", (signed)migrationLevel, (signed)MPMigrationLevelLocalStoreCurrent);
if (migrationLevel <= MPMigrationLevelLocalStoreV1) if (migrationLevel <= MPMigrationLevelLocalStoreV1)
[self migrateV1LocalStore]; if (![self migrateV1LocalStore]) {
inf(@"Failed to migrate old V1 to new local store.");
return;
}
[[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelLocalStoreCurrent forKey:MPMigrationLevelLocalStoreKey]; [[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelLocalStoreCurrent forKey:MPMigrationLevelLocalStoreKey];
inf(@"Successfully migrated old to new local store."); inf(@"Successfully migrated old to new local store.");
@ -156,15 +159,24 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
return; return;
inf(@"Cloud store migration level: %d (current %d)", (signed)migrationLevel, (signed)MPMigrationLevelCloudStoreCurrent); inf(@"Cloud store migration level: %d (current %d)", (signed)migrationLevel, (signed)MPMigrationLevelCloudStoreCurrent);
if (migrationLevel <= MPMigrationLevelCloudStoreV1) if (migrationLevel <= MPMigrationLevelCloudStoreV1) {
[self migrateV1CloudStore]; if (![self migrateV1CloudStore]) {
else if (migrationLevel <= MPMigrationLevelCloudStoreV2) inf(@"Failed to migrate old V1 to new cloud store.");
[self migrateV2CloudStore]; return;
}
[[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelCloudStoreCurrent forKey:MPMigrationLevelCloudStoreKey]; }
else if (migrationLevel <= MPMigrationLevelCloudStoreV2) {
if (![self migrateV2CloudStore]) {
inf(@"Failed to migrate old V2 to new cloud store.");
return;
}
} }
- (void)migrateV1CloudStore { [[NSUserDefaults standardUserDefaults] setInteger:MPMigrationLevelCloudStoreCurrent forKey:MPMigrationLevelCloudStoreKey];
inf(@"Successfully migrated old to new cloud store.");
}
- (BOOL)migrateV1CloudStore {
// Migrate cloud enabled preference. // Migrate cloud enabled preference.
NSNumber *oldCloudEnabled = [[NSUserDefaults standardUserDefaults] objectForKey:@"iCloudEnabledKey"]; NSNumber *oldCloudEnabled = [[NSUserDefaults standardUserDefaults] objectForKey:@"iCloudEnabledKey"];
@ -175,7 +187,7 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
NSString *uuid = [[NSUserDefaults standardUserDefaults] stringForKey:@"LocalUUIDKey"]; NSString *uuid = [[NSUserDefaults standardUserDefaults] stringForKey:@"LocalUUIDKey"];
if (!uuid) { if (!uuid) {
inf(@"No V1 cloud store to migrate."); inf(@"No V1 cloud store to migrate.");
return; return YES;
} }
inf(@"Migrating V1 cloud store: %@ -> %@", uuid, [self.storeManager valueForKey:@"storeUUID"]); inf(@"Migrating V1 cloud store: %@ -> %@", uuid, [self.storeManager valueForKey:@"storeUUID"]);
@ -187,16 +199,16 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
URLByAppendingPathComponent:@"Database.nosync" isDirectory:YES] URLByAppendingPathComponent:@"Database.nosync" isDirectory:YES]
URLByAppendingPathComponent:uuid isDirectory:NO] URLByAppendingPathExtension:@"sqlite"]; URLByAppendingPathComponent:uuid isDirectory:NO] URLByAppendingPathExtension:@"sqlite"];
[self migrateFromCloudStore:oldCloudStoreURL cloudContent:oldCloudContentURL contentName:uuid]; return [self migrateFromCloudStore:oldCloudStoreURL cloudContent:oldCloudContentURL contentName:uuid];
} }
- (void)migrateV2CloudStore { - (BOOL)migrateV2CloudStore {
// Migrate cloud store. // Migrate cloud store.
NSString *uuid = [[NSUbiquitousKeyValueStore defaultStore] stringForKey:@"USMStoreUUIDKey"]; NSString *uuid = [[NSUbiquitousKeyValueStore defaultStore] stringForKey:@"USMStoreUUIDKey"];
if (!uuid) { if (!uuid) {
inf(@"No V2 cloud store to migrate."); inf(@"No V2 cloud store to migrate.");
return; return YES;
} }
inf(@"Migrating V2 cloud store: %@ -> %@", uuid, [self.storeManager valueForKey:@"storeUUID"]); inf(@"Migrating V2 cloud store: %@ -> %@", uuid, [self.storeManager valueForKey:@"storeUUID"]);
@ -208,10 +220,10 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
URLByAppendingPathComponent:@"CloudStore.nosync" isDirectory:YES] URLByAppendingPathComponent:@"CloudStore.nosync" isDirectory:YES]
URLByAppendingPathComponent:uuid isDirectory:NO] URLByAppendingPathExtension:@"sqlite"]; URLByAppendingPathComponent:uuid isDirectory:NO] URLByAppendingPathExtension:@"sqlite"];
[self migrateFromCloudStore:oldCloudStoreURL cloudContent:oldCloudContentURL contentName:uuid]; return [self migrateFromCloudStore:oldCloudStoreURL cloudContent:oldCloudContentURL contentName:uuid];
} }
- (void)migrateV1LocalStore { - (BOOL)migrateV1LocalStore {
NSURL *applicationFilesDirectory = [[[NSFileManager defaultManager] NSURL *applicationFilesDirectory = [[[NSFileManager defaultManager]
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
@ -219,19 +231,19 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
URLByAppendingPathComponent:@"MasterPassword" isDirectory:NO] URLByAppendingPathExtension:@"sqlite"]; URLByAppendingPathComponent:@"MasterPassword" isDirectory:NO] URLByAppendingPathExtension:@"sqlite"];
if (![[NSFileManager defaultManager] fileExistsAtPath:oldLocalStoreURL.path isDirectory:NO]) { if (![[NSFileManager defaultManager] fileExistsAtPath:oldLocalStoreURL.path isDirectory:NO]) {
inf(@"No V1 local store to migrate."); inf(@"No V1 local store to migrate.");
return; return YES;
} }
inf(@"Migrating V1 local store"); inf(@"Migrating V1 local store");
[self migrateFromLocalStore:oldLocalStoreURL]; return [self migrateFromLocalStore:oldLocalStoreURL];
} }
- (void)migrateFromLocalStore:(NSURL *)oldLocalStoreURL { - (BOOL)migrateFromLocalStore:(NSURL *)oldLocalStoreURL {
NSURL *newLocalStoreURL = [self.storeManager URLForLocalStore]; NSURL *newLocalStoreURL = [self.storeManager URLForLocalStore];
if ([[NSFileManager defaultManager] fileExistsAtPath:newLocalStoreURL.path isDirectory:NO]) { if ([[NSFileManager defaultManager] fileExistsAtPath:newLocalStoreURL.path isDirectory:NO]) {
wrn(@"Can't migrate local store: A new local store already exists."); wrn(@"Can't migrate local store: A new local store already exists.");
return; return YES;
} }
NSError *error = nil; NSError *error = nil;
@ -253,17 +265,20 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
if (![self.storeManager copyMigrateStore:oldLocalStoreURL withOptions:oldLocalStoreOptions if (![self.storeManager copyMigrateStore:oldLocalStoreURL withOptions:oldLocalStoreOptions
toStore:newLocalStoreURL withOptions:newLocalStoreOptions toStore:newLocalStoreURL withOptions:newLocalStoreOptions
error:nil cause:nil context:nil]) error:nil cause:nil context:nil]) {
return; self.storeManager.localStoreURL = oldLocalStoreURL;
return NO;
inf(@"Successfully migrated to new local store.");
} }
- (void)migrateFromCloudStore:(NSURL *)oldCloudStoreURL cloudContent:(NSURL *)oldCloudContentURL contentName:(NSString *)contentName { inf(@"Successfully migrated to new local store.");
return YES;
}
- (BOOL)migrateFromCloudStore:(NSURL *)oldCloudStoreURL cloudContent:(NSURL *)oldCloudContentURL contentName:(NSString *)contentName {
if (![self.storeManager cloudSafeForSeeding]) { if (![self.storeManager cloudSafeForSeeding]) {
inf(@"Can't migrate cloud store: A new cloud store already exists."); inf(@"Can't migrate cloud store: A new cloud store already exists.");
return; return YES;
} }
NSURL *newCloudStoreURL = [self.storeManager URLForCloudStore]; NSURL *newCloudStoreURL = [self.storeManager URLForCloudStore];
@ -302,9 +317,10 @@ PearlAssociatedObjectProperty(NSManagedObjectContext*, MainManagedObjectContext,
if (![self.storeManager copyMigrateStore:oldCloudStoreURL withOptions:oldCloudStoreOptions if (![self.storeManager copyMigrateStore:oldCloudStoreURL withOptions:oldCloudStoreOptions
toStore:newCloudStoreURL withOptions:newCloudStoreOptions toStore:newCloudStoreURL withOptions:newCloudStoreOptions
error:nil cause:nil context:nil]) error:nil cause:nil context:nil])
return; return NO;
inf(@"Successfully migrated to new cloud store."); inf(@"Successfully migrated to new cloud store.");
return YES;
} }
#pragma mark - UbiquityStoreManagerDelegate #pragma mark - UbiquityStoreManagerDelegate