diff --git a/ApptentiveConnect/ApptentiveConnect.xcodeproj/project.pbxproj b/ApptentiveConnect/ApptentiveConnect.xcodeproj/project.pbxproj index e0c660b9c..757047d6c 100644 --- a/ApptentiveConnect/ApptentiveConnect.xcodeproj/project.pbxproj +++ b/ApptentiveConnect/ApptentiveConnect.xcodeproj/project.pbxproj @@ -258,6 +258,11 @@ 49E6208716C5E8C2000C9F5A /* NSDictionary+ATAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 49E6208516C5E8C2000C9F5A /* NSDictionary+ATAdditions.h */; }; 49E6208816C5E8C2000C9F5A /* NSDictionary+ATAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 49E6208616C5E8C2000C9F5A /* NSDictionary+ATAdditions.m */; }; 49E6208916C5E8C2000C9F5A /* NSDictionary+ATAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 49E6208616C5E8C2000C9F5A /* NSDictionary+ATAdditions.m */; }; + 49E7408618403A7D00413697 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58805F3818120DE100210DA5 /* Accelerate.framework */; }; + 49E7408818403E6200413697 /* v2CorruptDatabase in Resources */ = {isa = PBXBuildFile; fileRef = 49E7408718403E6200413697 /* v2CorruptDatabase */; }; + 49E7408B184045C900413697 /* v2WALDatabase in Resources */ = {isa = PBXBuildFile; fileRef = 49E7408A184045C900413697 /* v2WALDatabase */; }; + 49E7408F1840497600413697 /* v3WALDatabase in Resources */ = {isa = PBXBuildFile; fileRef = 49E7408E1840497600413697 /* v3WALDatabase */; }; + 49E740911840498100413697 /* ATDataModelv3.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 49E740901840498100413697 /* ATDataModelv3.sqlite */; }; 49E847A117E921B800CFA6EC /* ATMessageInputViewV7.xib in Resources */ = {isa = PBXBuildFile; fileRef = 49E847A017E921B800CFA6EC /* ATMessageInputViewV7.xib */; }; 49E891D0134FE2AB00DD098A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 49E891CD134FE2AB00DD098A /* Localizable.strings */; }; 49EA5AB014BD08AD004F8A4D /* ATLegacyRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 49EA5AAE14BD08AD004F8A4D /* ATLegacyRecord.h */; }; @@ -294,6 +299,8 @@ 49F8AFFC16CC4D860070FFEA /* ATRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 49F8AFFA16CC4D860070FFEA /* ATRecord.m */; }; 49F8AFFF16CC56580070FFEA /* ATEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 49F8AFFD16CC56570070FFEA /* ATEvent.h */; }; 49F8B00016CC56580070FFEA /* ATEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 49F8AFFE16CC56570070FFEA /* ATEvent.m */; }; + 49FECBE317D02BAD00069502 /* ATDataModel v1 to v2.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 49FECBE217D02BAD00069502 /* ATDataModel v1 to v2.xcmappingmodel */; }; + 49FECBE417D02BAD00069502 /* ATDataModel v1 to v2.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 49FECBE217D02BAD00069502 /* ATDataModel v1 to v2.xcmappingmodel */; }; 580B24BB17D90AF300AE2CD0 /* ATEngagementTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 580B24BA17D90AF300AE2CD0 /* ATEngagementTests.m */; }; 584647C617C426E800BFD6E6 /* ATEngagementManifestParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 584647C417C426E800BFD6E6 /* ATEngagementManifestParser.h */; }; 584647C717C426E800BFD6E6 /* ATEngagementManifestParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 584647C517C426E800BFD6E6 /* ATEngagementManifestParser.m */; }; @@ -307,6 +314,7 @@ 5898DF8C17C2E0CE0048F11F /* ATEngagementGetManifestTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 5898DF8A17C2E0CE0048F11F /* ATEngagementGetManifestTask.h */; }; 5898DF8D17C2E0CE0048F11F /* ATEngagementGetManifestTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 5898DF8B17C2E0CE0048F11F /* ATEngagementGetManifestTask.m */; }; 5898DF8E17C2E0CE0048F11F /* ATEngagementGetManifestTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 5898DF8B17C2E0CE0048F11F /* ATEngagementGetManifestTask.m */; }; + 58AA40A01821C162000799D8 /* ATDataModelv2.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 58AA409F1821C162000799D8 /* ATDataModelv2.sqlite */; }; 58C5922117C55ADD000FA428 /* ATEngagementBackend.h in Headers */ = {isa = PBXBuildFile; fileRef = 58C5921F17C55ADD000FA428 /* ATEngagementBackend.h */; }; 58C5922217C55ADD000FA428 /* ATEngagementBackend.m in Sources */ = {isa = PBXBuildFile; fileRef = 58C5922017C55ADD000FA428 /* ATEngagementBackend.m */; }; 58C5922317C55ADD000FA428 /* ATEngagementBackend.m in Sources */ = {isa = PBXBuildFile; fileRef = 58C5922017C55ADD000FA428 /* ATEngagementBackend.m */; }; @@ -319,6 +327,8 @@ 58C97B5C18276427001EB5BD /* UIViewController+ATSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = 58C97B5A18276427001EB5BD /* UIViewController+ATSwizzle.h */; }; 58C97B5D18276427001EB5BD /* UIViewController+ATSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 58C97B5B18276427001EB5BD /* UIViewController+ATSwizzle.m */; }; 58C97B5E18276427001EB5BD /* UIViewController+ATSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 58C97B5B18276427001EB5BD /* UIViewController+ATSwizzle.m */; }; + 58CD20151821B7A70071CC72 /* ATDataModel v2 to v3.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 58CD20131821B78D0071CC72 /* ATDataModel v2 to v3.xcmappingmodel */; }; + 58CD20161821B7A80071CC72 /* ATDataModel v2 to v3.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 58CD20131821B78D0071CC72 /* ATDataModel v2 to v3.xcmappingmodel */; }; 58DCC0D5180F445700A3A7AE /* ATInteractionUpgradeMessageViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 58DCC0D2180F445700A3A7AE /* ATInteractionUpgradeMessageViewController.h */; }; 58DCC0D6180F445700A3A7AE /* ATInteractionUpgradeMessageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 58DCC0D3180F445700A3A7AE /* ATInteractionUpgradeMessageViewController.m */; }; 58DCC0D7180F445700A3A7AE /* ATInteractionUpgradeMessageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 58DCC0D3180F445700A3A7AE /* ATInteractionUpgradeMessageViewController.m */; }; @@ -327,11 +337,6 @@ 58EEBE2317C7E8150039A0F5 /* ATInteraction.h in Headers */ = {isa = PBXBuildFile; fileRef = 58EEBE2117C7E8150039A0F5 /* ATInteraction.h */; }; 58EEBE2417C7E8150039A0F5 /* ATInteraction.m in Sources */ = {isa = PBXBuildFile; fileRef = 58EEBE2217C7E8150039A0F5 /* ATInteraction.m */; }; 58EEBE2517C7E8150039A0F5 /* ATInteraction.m in Sources */ = {isa = PBXBuildFile; fileRef = 58EEBE2217C7E8150039A0F5 /* ATInteraction.m */; }; - 49FECBE317D02BAD00069502 /* ATDataModel v1 to v2.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 49FECBE217D02BAD00069502 /* ATDataModel v1 to v2.xcmappingmodel */; }; - 49FECBE417D02BAD00069502 /* ATDataModel v1 to v2.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 49FECBE217D02BAD00069502 /* ATDataModel v1 to v2.xcmappingmodel */; }; - 58AA40A01821C162000799D8 /* ATDataModelv2.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 58AA409F1821C162000799D8 /* ATDataModelv2.sqlite */; }; - 58CD20151821B7A70071CC72 /* ATDataModel v2 to v3.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 58CD20131821B78D0071CC72 /* ATDataModel v2 to v3.xcmappingmodel */; }; - 58CD20161821B7A80071CC72 /* ATDataModel v2 to v3.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 58CD20131821B78D0071CC72 /* ATDataModel v2 to v3.xcmappingmodel */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -562,6 +567,10 @@ 49E3A26E1628F4FF000675B4 /* ATGetMessagesTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ATGetMessagesTask.m; path = "Message Center/Tasks/ATGetMessagesTask.m"; sourceTree = ""; }; 49E6208516C5E8C2000C9F5A /* NSDictionary+ATAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+ATAdditions.h"; sourceTree = ""; }; 49E6208616C5E8C2000C9F5A /* NSDictionary+ATAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+ATAdditions.m"; sourceTree = ""; }; + 49E7408718403E6200413697 /* v2CorruptDatabase */ = {isa = PBXFileReference; lastKnownFileType = folder; path = v2CorruptDatabase; sourceTree = ""; }; + 49E7408A184045C900413697 /* v2WALDatabase */ = {isa = PBXFileReference; lastKnownFileType = folder; path = v2WALDatabase; sourceTree = ""; }; + 49E7408E1840497600413697 /* v3WALDatabase */ = {isa = PBXFileReference; lastKnownFileType = folder; path = v3WALDatabase; sourceTree = ""; }; + 49E740901840498100413697 /* ATDataModelv3.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = ATDataModelv3.sqlite; sourceTree = ""; }; 49E847A017E921B800CFA6EC /* ATMessageInputViewV7.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ATMessageInputViewV7.xib; sourceTree = ""; }; 49E891CF134FE2AB00DD098A /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; 49EA5AAE14BD08AD004F8A4D /* ATLegacyRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ATLegacyRecord.h; sourceTree = ""; }; @@ -595,6 +604,7 @@ 49F8AFFA16CC4D860070FFEA /* ATRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ATRecord.m; sourceTree = ""; }; 49F8AFFD16CC56570070FFEA /* ATEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ATEvent.h; sourceTree = ""; }; 49F8AFFE16CC56570070FFEA /* ATEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ATEvent.m; sourceTree = ""; }; + 49FECBE217D02BAD00069502 /* ATDataModel v1 to v2.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = "ATDataModel v1 to v2.xcmappingmodel"; sourceTree = ""; }; 580B24B917D90AF300AE2CD0 /* ATEngagementTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ATEngagementTests.h; sourceTree = ""; }; 580B24BA17D90AF300AE2CD0 /* ATEngagementTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ATEngagementTests.m; sourceTree = ""; }; 584647C417C426E800BFD6E6 /* ATEngagementManifestParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ATEngagementManifestParser.h; path = Engagement/Model/ATEngagementManifestParser.h; sourceTree = ""; }; @@ -606,6 +616,7 @@ 589274A5180CC33A0029E5CE /* ATInteractionUsageData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ATInteractionUsageData.m; path = Engagement/Model/ATInteractionUsageData.m; sourceTree = ""; }; 5898DF8A17C2E0CE0048F11F /* ATEngagementGetManifestTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ATEngagementGetManifestTask.h; path = source/Engagement/Tasks/ATEngagementGetManifestTask.h; sourceTree = SOURCE_ROOT; }; 5898DF8B17C2E0CE0048F11F /* ATEngagementGetManifestTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ATEngagementGetManifestTask.m; path = source/Engagement/Tasks/ATEngagementGetManifestTask.m; sourceTree = SOURCE_ROOT; }; + 58AA409F1821C162000799D8 /* ATDataModelv2.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = ATDataModelv2.sqlite; sourceTree = ""; }; 58C5921F17C55ADD000FA428 /* ATEngagementBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ATEngagementBackend.h; path = Engagement/Persistence/ATEngagementBackend.h; sourceTree = ""; }; 58C5922017C55ADD000FA428 /* ATEngagementBackend.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ATEngagementBackend.m; path = Engagement/Persistence/ATEngagementBackend.m; sourceTree = ""; }; 58C5922917C59BE3000FA428 /* ATWebClient+EngagementAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ATWebClient+EngagementAdditions.h"; path = "Engagement/URL Loading/ATWebClient+EngagementAdditions.h"; sourceTree = ""; }; @@ -614,13 +625,11 @@ 58C97B56182752F6001EB5BD /* NSObject+ATSwizzle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+ATSwizzle.m"; sourceTree = ""; }; 58C97B5A18276427001EB5BD /* UIViewController+ATSwizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+ATSwizzle.h"; sourceTree = ""; }; 58C97B5B18276427001EB5BD /* UIViewController+ATSwizzle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+ATSwizzle.m"; sourceTree = ""; }; + 58CD20121821B4D40071CC72 /* ATDataModel 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "ATDataModel 3.xcdatamodel"; sourceTree = ""; }; + 58CD20131821B78D0071CC72 /* ATDataModel v2 to v3.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = "ATDataModel v2 to v3.xcmappingmodel"; sourceTree = ""; }; 58DCC0D2180F445700A3A7AE /* ATInteractionUpgradeMessageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ATInteractionUpgradeMessageViewController.h; sourceTree = ""; }; 58DCC0D3180F445700A3A7AE /* ATInteractionUpgradeMessageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ATInteractionUpgradeMessageViewController.m; sourceTree = ""; }; 58DCC0D4180F445700A3A7AE /* ATInteractionUpgradeMessageViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ATInteractionUpgradeMessageViewController.xib; sourceTree = ""; }; - 49FECBE217D02BAD00069502 /* ATDataModel v1 to v2.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = "ATDataModel v1 to v2.xcmappingmodel"; sourceTree = ""; }; - 58AA409F1821C162000799D8 /* ATDataModelv2.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = ATDataModelv2.sqlite; sourceTree = ""; }; - 58CD20121821B4D40071CC72 /* ATDataModel 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "ATDataModel 3.xcdatamodel"; sourceTree = ""; }; - 58CD20131821B78D0071CC72 /* ATDataModel v2 to v3.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = "ATDataModel v2 to v3.xcmappingmodel"; sourceTree = ""; }; 58EA5B3617B4781600ECEB4B /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; 58EA5B3B17B479A500ECEB4B /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; 58EA5B4117B47AAC00ECEB4B /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Localizable.strings; sourceTree = ""; }; @@ -653,6 +662,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 49E7408618403A7D00413697 /* Accelerate.framework in Frameworks */, 49F3404E16BC8B1A008AA02B /* StoreKit.framework in Frameworks */, 496DC38F1333D35600743F65 /* Foundation.framework in Frameworks */, 496DC3941333D35600743F65 /* libApptentiveConnect.a in Frameworks */, @@ -1116,8 +1126,12 @@ 49C54BD61790B783009CCD5D /* data */ = { isa = PBXGroup; children = ( + 49E7408718403E6200413697 /* v2CorruptDatabase */, + 49E7408A184045C900413697 /* v2WALDatabase */, + 49E7408E1840497600413697 /* v3WALDatabase */, 49C54BD71790B783009CCD5D /* ATDataModelv1.sqlite */, 58AA409F1821C162000799D8 /* ATDataModelv2.sqlite */, + 49E740901840498100413697 /* ATDataModelv3.sqlite */, ); path = data; sourceTree = ""; @@ -1500,8 +1514,12 @@ 49AA1023138B498C0082887A /* ATInfoViewController.xib in Resources */, 58AA40A01821C162000799D8 /* ATDataModelv2.sqlite in Resources */, 49AA1025138B49A50082887A /* ATInfoViewController_iPad.xib in Resources */, + 49E7408B184045C900413697 /* v2WALDatabase in Resources */, + 49E7408818403E6200413697 /* v2CorruptDatabase in Resources */, 58DCC0D9180F445700A3A7AE /* ATInteractionUpgradeMessageViewController.xib in Resources */, + 49E7408F1840497600413697 /* v3WALDatabase in Resources */, 49352A21138C73B8000E464A /* ATAboutApptentiveView.xib in Resources */, + 49E740911840498100413697 /* ATDataModelv3.sqlite in Resources */, 49C54BD51790A95E009CCD5D /* ApptentiveResources.bundle in Resources */, 49C54BD81790B783009CCD5D /* ATDataModelv1.sqlite in Resources */, ); diff --git a/ApptentiveConnect/source/ATConnect.h b/ApptentiveConnect/source/ATConnect.h index b29c2b419..dc1b1f023 100644 --- a/ApptentiveConnect/source/ATConnect.h +++ b/ApptentiveConnect/source/ATConnect.h @@ -13,7 +13,7 @@ #import #endif -#define kATConnectVersionString @"1.2.3a" +#define kATConnectVersionString @"1.2.3" #if TARGET_OS_IPHONE # define kATConnectPlatformString @"iOS" diff --git a/ApptentiveConnect/source/Persistence/ATDataManager.h b/ApptentiveConnect/source/Persistence/ATDataManager.h index 5ee24609e..69bcfe778 100644 --- a/ApptentiveConnect/source/Persistence/ATDataManager.h +++ b/ApptentiveConnect/source/Persistence/ATDataManager.h @@ -16,6 +16,9 @@ extern NSString *const ATDataManagerUpgradeCanaryKey; @property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; @property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; @property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; +@property (nonatomic, readonly) BOOL didRemovePersistentStore; +@property (nonatomic, readonly) BOOL didFailToMigrateStore; +@property (nonatomic, readonly) BOOL didMigrateStore; - (id)initWithModelName:(NSString *)modelName inBundle:(NSBundle *)bundle storagePath:(NSString *)path; diff --git a/ApptentiveConnect/source/Persistence/ATDataManager.m b/ApptentiveConnect/source/Persistence/ATDataManager.m index 1ba51c5bd..20fb453fc 100644 --- a/ApptentiveConnect/source/Persistence/ATDataManager.m +++ b/ApptentiveConnect/source/Persistence/ATDataManager.m @@ -32,6 +32,7 @@ @implementation ATDataManager { NSBundle *bundle; NSString *supportDirectoryPath; } +@synthesize didRemovePersistentStore, didFailToMigrateStore, didMigrateStore; - (id)initWithModelName:(NSString *)aModelName inBundle:(NSBundle *)aBundle storagePath:(NSString *)path { if ((self = [super init])) { @@ -149,7 +150,10 @@ - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (storeExists && [self isMigrationNecessary:persistentStoreCoordinator]) { if (![self migrateStoreError:&error]) { ATLogError(@"Failed to migrate store. Need to start over from scratch: %@", error); + didFailToMigrateStore = YES; [self removePersistentStore]; + } else { + didMigrateStore = YES; } } @@ -185,6 +189,7 @@ - (void)removePersistentStore { } } [self removeSQLiteSidecarsForPath:sourcePath]; + didRemovePersistentStore = YES; } @end diff --git a/ApptentiveConnect/tests/ApptentiveMigrationTests.m b/ApptentiveConnect/tests/ApptentiveMigrationTests.m index 7d0331181..281a9a165 100644 --- a/ApptentiveConnect/tests/ApptentiveMigrationTests.m +++ b/ApptentiveConnect/tests/ApptentiveMigrationTests.m @@ -10,7 +10,7 @@ #import "ATDataManager.h" @implementation ApptentiveMigrationTests -- (void)performTestWithStoreName:(NSString *)name { +- (ATDataManager *)dataManagerWithStoreName:(NSString *)name { NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSURL *storeURL = [bundle URLForResource:name withExtension:@"sqlite"]; @@ -24,18 +24,107 @@ - (void)performTestWithStoreName:(NSString *)name { [fileManager removeItemAtURL:[dataManager persistentStoreURL] error:nil]; if (![fileManager copyItemAtURL:storeURL toURL:[dataManager persistentStoreURL] error:&error]) { STFail(@"Unable to copy item: %@", error); - return; + [dataManager release]; + return nil; } - - STAssertNotNil([dataManager persistentStoreCoordinator], @"Shouldn't be nil"); + return dataManager; } - (void)testV1Upgrade { // For example, we will do the following with a copy of an old data model. - [self performTestWithStoreName:@"ATDataModelv1"]; + ATDataManager *dataManager = [self dataManagerWithStoreName:@"ATDataModelv1"]; + + STAssertTrue([dataManager setupAndVerify], @"Should be able to setup database."); + STAssertNotNil([dataManager persistentStoreCoordinator], @"Shouldn't be nil"); + STAssertTrue([dataManager didMigrateStore], @"Should have had to migrate the datastore."); + STAssertFalse([dataManager didFailToMigrateStore], @"Failed to migrate the datastore."); + STAssertFalse([dataManager didRemovePersistentStore], @"Shouldn't have had to delete datastore."); + [dataManager release]; } - (void)testV2Upgrade { - [self performTestWithStoreName:@"ATDataModelv2"]; + ATDataManager *dataManager = [self dataManagerWithStoreName:@"ATDataModelv2"]; + + STAssertTrue([dataManager setupAndVerify], @"Should be able to setup database."); + STAssertNotNil([dataManager persistentStoreCoordinator], @"Shouldn't be nil"); + STAssertTrue([dataManager didMigrateStore], @"Should have had to migrate the datastore."); + STAssertFalse([dataManager didFailToMigrateStore], @"Failed to migrate the datastore."); + STAssertFalse([dataManager didRemovePersistentStore], @"Shouldn't have had to delete datastore."); + [dataManager release]; +} + +- (void)testCurrentDatabaseVersion { + ATDataManager *dataManager = [self dataManagerWithStoreName:@"ATDataModelv3"]; + + STAssertTrue([dataManager setupAndVerify], @"Should be able to setup database."); + STAssertNotNil([dataManager persistentStoreCoordinator], @"Shouldn't be nil"); + STAssertFalse([dataManager didMigrateStore], @"Should not have had to migrate the datastore."); + STAssertFalse([dataManager didFailToMigrateStore], @"Failed to migrate the datastore."); + STAssertFalse([dataManager didRemovePersistentStore], @"Shouldn't have had to delete datastore."); + [dataManager release]; +} + +- (ATDataManager *)dataManagerByCopyingSQLFilesInDirectory:(NSString *)directoryName { + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; + NSArray *files = @[@"ATDataModel.sqlite", @"ATDataModel.sqlite-shm", @"ATDataModel.sqlite-wal"]; + + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); + NSString *path = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; + + for (NSString *filename in files) { + NSString *name = [filename stringByDeletingPathExtension]; + NSString *extension = [filename pathExtension]; + + NSString *source = [bundle pathForResource:name ofType:extension inDirectory:directoryName]; + NSString *destination = [path stringByAppendingPathComponent:filename]; + NSError *error = nil; + + [fileManager removeItemAtPath:destination error:nil]; + if (![fileManager fileExistsAtPath:source isDirectory:NULL]) { + STFail(@"Unable to find file: %@", source); + } + if (![fileManager copyItemAtPath:source toPath:destination error:&error]) { + STFail(@"Unable to copy item: %@", error); + return nil; + } + } + + ATDataManager *dataManager = [[ATDataManager alloc] initWithModelName:@"ATDataModel" inBundle:bundle storagePath:path]; + return dataManager; +} + +- (void)testV2WALDatabase { + // A valid v2 database, albeit in WAL format. + ATDataManager *dataManager = [self dataManagerByCopyingSQLFilesInDirectory:@"v2WALDatabase"]; + + STAssertTrue([dataManager setupAndVerify], @"Should be able to setup database."); + STAssertNotNil([dataManager persistentStoreCoordinator], @"Should be able to use existing WAL database."); + STAssertTrue([dataManager didMigrateStore], @"Should have had to migrate the datastore."); + STAssertFalse([dataManager didFailToMigrateStore], @"Should not have failed to migrate the persistent store."); + STAssertFalse([dataManager didRemovePersistentStore], @"Should not have had to delete the persistent store."); + [dataManager release]; +} + +- (void)testV3WALDatabase { + // A valid v3 database, albeit in WAL format. + ATDataManager *dataManager = [self dataManagerByCopyingSQLFilesInDirectory:@"v3WALDatabase"]; + + STAssertTrue([dataManager setupAndVerify], @"Should be able to setup database."); + STAssertNotNil([dataManager persistentStoreCoordinator], @"Should be able to use existing WAL database."); + STAssertFalse([dataManager didMigrateStore], @"Should not have had to migrate the datastore."); + STAssertFalse([dataManager didFailToMigrateStore], @"Should not have failed to migrate the persistent store."); + STAssertFalse([dataManager didRemovePersistentStore], @"Should not have had to delete the persistent store."); + [dataManager release]; +} + +- (void)testCorruptV2DatabaseRecovery { + // A corrupt v3 database in WAL format. + ATDataManager *dataManager = [self dataManagerByCopyingSQLFilesInDirectory:@"v2CorruptDatabase"]; + + STAssertTrue([dataManager setupAndVerify], @"Should be able to setup database."); + STAssertNotNil([dataManager persistentStoreCoordinator], @"Shouldn't be nil after fixing it."); + STAssertTrue([dataManager didRemovePersistentStore], @"Should have had to delete the persistent store."); + [dataManager release]; } @end diff --git a/ApptentiveConnect/tests/data/ATDataModelv2.sqlite b/ApptentiveConnect/tests/data/ATDataModelv2.sqlite index e9d7ccbf1..f1d6c258e 100644 Binary files a/ApptentiveConnect/tests/data/ATDataModelv2.sqlite and b/ApptentiveConnect/tests/data/ATDataModelv2.sqlite differ diff --git a/ApptentiveConnect/tests/data/ATDataModelv3.sqlite b/ApptentiveConnect/tests/data/ATDataModelv3.sqlite new file mode 100644 index 000000000..360576792 Binary files /dev/null and b/ApptentiveConnect/tests/data/ATDataModelv3.sqlite differ diff --git a/ApptentiveConnect/tests/data/v2CorruptDatabase/ATDataModel.sqlite b/ApptentiveConnect/tests/data/v2CorruptDatabase/ATDataModel.sqlite new file mode 100644 index 000000000..cf4ba50a3 Binary files /dev/null and b/ApptentiveConnect/tests/data/v2CorruptDatabase/ATDataModel.sqlite differ diff --git a/ApptentiveConnect/tests/data/v2CorruptDatabase/ATDataModel.sqlite-shm b/ApptentiveConnect/tests/data/v2CorruptDatabase/ATDataModel.sqlite-shm new file mode 100644 index 000000000..fe9ac2845 Binary files /dev/null and b/ApptentiveConnect/tests/data/v2CorruptDatabase/ATDataModel.sqlite-shm differ diff --git a/ApptentiveConnect/tests/data/v2CorruptDatabase/ATDataModel.sqlite-wal b/ApptentiveConnect/tests/data/v2CorruptDatabase/ATDataModel.sqlite-wal new file mode 100644 index 000000000..e69de29bb diff --git a/ApptentiveConnect/tests/data/v2WALDatabase/ATDataModel.sqlite b/ApptentiveConnect/tests/data/v2WALDatabase/ATDataModel.sqlite new file mode 100644 index 000000000..e982144ee Binary files /dev/null and b/ApptentiveConnect/tests/data/v2WALDatabase/ATDataModel.sqlite differ diff --git a/ApptentiveConnect/tests/data/v2WALDatabase/ATDataModel.sqlite-shm b/ApptentiveConnect/tests/data/v2WALDatabase/ATDataModel.sqlite-shm new file mode 100644 index 000000000..5d6e41e1c Binary files /dev/null and b/ApptentiveConnect/tests/data/v2WALDatabase/ATDataModel.sqlite-shm differ diff --git a/ApptentiveConnect/tests/data/v2WALDatabase/ATDataModel.sqlite-wal b/ApptentiveConnect/tests/data/v2WALDatabase/ATDataModel.sqlite-wal new file mode 100644 index 000000000..0d6791086 Binary files /dev/null and b/ApptentiveConnect/tests/data/v2WALDatabase/ATDataModel.sqlite-wal differ diff --git a/ApptentiveConnect/tests/data/v3WALDatabase/ATDataModel.sqlite b/ApptentiveConnect/tests/data/v3WALDatabase/ATDataModel.sqlite new file mode 100644 index 000000000..9eaefeb17 Binary files /dev/null and b/ApptentiveConnect/tests/data/v3WALDatabase/ATDataModel.sqlite differ diff --git a/ApptentiveConnect/tests/data/v3WALDatabase/ATDataModel.sqlite-shm b/ApptentiveConnect/tests/data/v3WALDatabase/ATDataModel.sqlite-shm new file mode 100644 index 000000000..98fe1b659 Binary files /dev/null and b/ApptentiveConnect/tests/data/v3WALDatabase/ATDataModel.sqlite-shm differ diff --git a/ApptentiveConnect/tests/data/v3WALDatabase/ATDataModel.sqlite-wal b/ApptentiveConnect/tests/data/v3WALDatabase/ATDataModel.sqlite-wal new file mode 100644 index 000000000..6329f7fa9 Binary files /dev/null and b/ApptentiveConnect/tests/data/v3WALDatabase/ATDataModel.sqlite-wal differ