diff --git a/README.md b/README.md index b3293a8..4500c76 100644 --- a/README.md +++ b/README.md @@ -308,7 +308,7 @@ public protocol LocalStorage: StorageInterface { var mappingModelBundles: [NSBundle] { get } var localStorageOptions: LocalStorageOptions { get } func storeOptionsForOptions(options: LocalStorageOptions) -> [String: AnyObject]? - func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel) throws + func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel?) throws } ``` If you have custom `NSIncrementalStore` or `NSAtomicStore` subclasses, you can implement this protocol and use it similarly to `SQLiteStore`. diff --git a/Sources/Migrating/DataStack+Migration.swift b/Sources/Migrating/DataStack+Migration.swift index d8d50cb..0924e85 100644 --- a/Sources/Migrating/DataStack+Migration.swift +++ b/Sources/Migrating/DataStack+Migration.swift @@ -223,7 +223,7 @@ public extension DataStack { do { - try _ = self.model[metadata].flatMap(storage.eraseStorageAndWait) + _ = try storage.eraseStorageAndWait(soureModel: self.model[metadata]) try self.addStorageAndWait(storage) GCDQueue.Main.async { @@ -388,7 +388,7 @@ public extension DataStack { URL: cacheFileURL, options: storeOptions ) - try _ = self.model[metadata].flatMap(storage.eraseStorageAndWait) + _ = try storage.eraseStorageAndWait(soureModel: self.model[metadata]) try self.createPersistentStoreFromStorage( storage, diff --git a/Sources/ObjectiveC/CSSQliteStore.swift b/Sources/ObjectiveC/CSSQliteStore.swift index 1b0a76c..0170026 100644 --- a/Sources/ObjectiveC/CSSQliteStore.swift +++ b/Sources/ObjectiveC/CSSQliteStore.swift @@ -154,7 +154,7 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT Called by the `CSDataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. For `CSSQLiteStore`, this converts the database's WAL journaling mode to DELETE before deleting the file. */ @objc - public func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel, error: NSErrorPointer) -> Bool { + public func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel?, error: NSErrorPointer) -> Bool { return bridge(error) { diff --git a/Sources/ObjectiveC/CSStorageInterface.swift b/Sources/ObjectiveC/CSStorageInterface.swift index 9696d8f..999f5b3 100644 --- a/Sources/ObjectiveC/CSStorageInterface.swift +++ b/Sources/ObjectiveC/CSStorageInterface.swift @@ -121,5 +121,5 @@ public protocol CSLocalStorage: CSStorageInterface { Called by the `CSDataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. Implementers can use the `sourceModel` to perform necessary store operations. (SQLite stores for example, can convert WAL journaling mode to DELETE before deleting) */ @objc - func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel, error: NSErrorPointer) -> Bool + func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel?, error: NSErrorPointer) -> Bool } diff --git a/Sources/Setup/DataStack.swift b/Sources/Setup/DataStack.swift index bad563c..99e2b17 100644 --- a/Sources/Setup/DataStack.swift +++ b/Sources/Setup/DataStack.swift @@ -263,7 +263,7 @@ public final class DataStack { URL: fileURL, options: storeOptions ) - try _ = self.model[metadata].flatMap(storage.eraseStorageAndWait) + _ = try storage.eraseStorageAndWait(soureModel: self.model[metadata]) try self.createPersistentStoreFromStorage( storage, @@ -359,7 +359,7 @@ public final class DataStack { URL: cacheFileURL, options: storeOptions ) - try _ = self.model[metadata].flatMap(storage.eraseStorageAndWait) + _ = try storage.eraseStorageAndWait(soureModel: self.model[metadata]) try self.createPersistentStoreFromStorage( storage, diff --git a/Sources/Setup/StorageInterfaces/ICloudStore.swift b/Sources/Setup/StorageInterfaces/ICloudStore.swift index 06e3e8f..2aecdd4 100644 --- a/Sources/Setup/StorageInterfaces/ICloudStore.swift +++ b/Sources/Setup/StorageInterfaces/ICloudStore.swift @@ -424,11 +424,19 @@ public class ICloudStore: CloudStorage { /** Called by the `DataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. For `SQLiteStore`, this converts the database's WAL journaling mode to DELETE before deleting the file. */ - public func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel) throws { + public func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel?) throws { // TODO: check if attached to persistent store let cacheFileURL = self.cacheFileURL + guard let soureModel = soureModel else { + + let fileManager = NSFileManager.defaultManager() + try fileManager.removeItemAtURL(cacheFileURL) + _ = try fileManager.removeItemAtPath("\(cacheFileURL.absoluteString)-wal") + _ = try fileManager.removeItemAtPath("\(cacheFileURL.absoluteString)-shm") + return + } try cs_autoreleasepool { let journalUpdatingCoordinator = NSPersistentStoreCoordinator(managedObjectModel: soureModel) diff --git a/Sources/Setup/StorageInterfaces/LegacySQLiteStore.swift b/Sources/Setup/StorageInterfaces/LegacySQLiteStore.swift index b72c0fc..a7414e1 100644 --- a/Sources/Setup/StorageInterfaces/LegacySQLiteStore.swift +++ b/Sources/Setup/StorageInterfaces/LegacySQLiteStore.swift @@ -165,11 +165,19 @@ public final class LegacySQLiteStore: LocalStorage, DefaultInitializableStore { /** Called by the `DataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. For `SQLiteStore`, this converts the database's WAL journaling mode to DELETE before deleting the file. */ - public func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel) throws { + public func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel?) throws { // TODO: check if attached to persistent store let fileURL = self.fileURL + guard let soureModel = soureModel else { + + let fileManager = NSFileManager.defaultManager() + try fileManager.removeItemAtURL(fileURL) + _ = try fileManager.removeItemAtPath("\(fileURL.absoluteString)-wal") + _ = try fileManager.removeItemAtPath("\(fileURL.absoluteString)-shm") + return + } try cs_autoreleasepool { let journalUpdatingCoordinator = NSPersistentStoreCoordinator(managedObjectModel: soureModel) diff --git a/Sources/Setup/StorageInterfaces/SQLiteStore.swift b/Sources/Setup/StorageInterfaces/SQLiteStore.swift index ee50d73..4a1d1a9 100644 --- a/Sources/Setup/StorageInterfaces/SQLiteStore.swift +++ b/Sources/Setup/StorageInterfaces/SQLiteStore.swift @@ -162,11 +162,19 @@ public final class SQLiteStore: LocalStorage, DefaultInitializableStore { /** Called by the `DataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. For `SQLiteStore`, this converts the database's WAL journaling mode to DELETE before deleting the file. */ - public func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel) throws { + public func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel?) throws { // TODO: check if attached to persistent store let fileURL = self.fileURL + guard let soureModel = soureModel else { + + let fileManager = NSFileManager.defaultManager() + try fileManager.removeItemAtURL(fileURL) + _ = try fileManager.removeItemAtPath("\(fileURL.absoluteString)-wal") + _ = try fileManager.removeItemAtPath("\(fileURL.absoluteString)-shm") + return + } try cs_autoreleasepool { let journalUpdatingCoordinator = NSPersistentStoreCoordinator(managedObjectModel: soureModel) diff --git a/Sources/Setup/StorageInterfaces/StorageInterface.swift b/Sources/Setup/StorageInterfaces/StorageInterface.swift index 63f37b2..3e10b3c 100644 --- a/Sources/Setup/StorageInterfaces/StorageInterface.swift +++ b/Sources/Setup/StorageInterfaces/StorageInterface.swift @@ -158,7 +158,7 @@ public protocol LocalStorage: StorageInterface { /** Called by the `DataStack` to perform actual deletion of the store file from disk. **Do not call directly!** The `sourceModel` argument is a hint for the existing store's model version. Implementers can use the `sourceModel` to perform necessary store operations. (SQLite stores for example, can convert WAL journaling mode to DELETE before deleting) */ - func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel) throws + func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel?) throws } internal extension LocalStorage { @@ -242,7 +242,7 @@ public protocol CloudStorage: StorageInterface { /** Called by the `DataStack` to perform actual deletion of the store file from disk. **Do not call directly!** The `sourceModel` argument is a hint for the existing store's model version. Implementers can use the `sourceModel` to perform necessary store operations. (Cloud stores for example, can set the NSPersistentStoreRemoveUbiquitousMetadataOption option before deleting) */ - func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel) throws + func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel?) throws } internal extension CloudStorage {