From d90e8d13030344295b1236af691f749104f23a8a Mon Sep 17 00:00:00 2001 From: John Rommel Estropia Date: Fri, 10 Nov 2017 02:48:37 +0900 Subject: [PATCH 1/6] force true lightweight migration --- Sources/DataStack+Migration.swift | 29 +++++++++++++++++-- .../NSPersistentStoreCoordinator+Setup.swift | 15 +++------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/Sources/DataStack+Migration.swift b/Sources/DataStack+Migration.swift index 4498e4b..0a19091 100644 --- a/Sources/DataStack+Migration.swift +++ b/Sources/DataStack+Migration.swift @@ -575,6 +575,7 @@ public extension DataStack { sourceModel: sourceModel, destinationModel: destinationModel, mappingModel: mappingModel, + migrationType: migrationType, progress: childProgress ) } @@ -679,10 +680,34 @@ public extension DataStack { return nil } - private func startMigrationForStorage(_ storage: T, sourceModel: NSManagedObjectModel, destinationModel: NSManagedObjectModel, mappingModel: NSMappingModel, progress: Progress) throws { + private func startMigrationForStorage(_ storage: T, sourceModel: NSManagedObjectModel, destinationModel: NSManagedObjectModel, mappingModel: NSMappingModel, migrationType: MigrationType, progress: Progress) throws { let fileURL = storage.fileURL - + if case .lightweight = migrationType { + + do { + + _ = try withExtendedLifetime(NSPersistentStoreCoordinator(managedObjectModel: destinationModel)) { (coordinator: NSPersistentStoreCoordinator) in + + try coordinator.addPersistentStoreSynchronously( + type(of: storage).storeType, + configuration: storage.configuration, + URL: fileURL, + options: storage.dictionary( + forOptions: storage.localStorageOptions.union(.allowSynchronousLightweightMigration) + ) + ) + } + _ = try? storage.cs_finalizeStorageAndWait(soureModelHint: destinationModel) + progress.completedUnitCount = progress.totalUnitCount + return + } + catch { + + // try manual migration + } + } + let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true) .appendingPathComponent(Bundle.main.bundleIdentifier ?? "com.CoreStore.DataStack") .appendingPathComponent(ProcessInfo().globallyUniqueString) diff --git a/Sources/NSPersistentStoreCoordinator+Setup.swift b/Sources/NSPersistentStoreCoordinator+Setup.swift index 8bba039..13aa538 100644 --- a/Sources/NSPersistentStoreCoordinator+Setup.swift +++ b/Sources/NSPersistentStoreCoordinator+Setup.swift @@ -72,15 +72,13 @@ internal extension NSPersistentStoreCoordinator { } @nonobjc - internal func addPersistentStoreSynchronously(_ storeType: String, configuration: ModelConfiguration, URL storeURL: URL?, options: [NSObject : AnyObject]?) throws -> NSPersistentStore { + internal func addPersistentStoreSynchronously(_ storeType: String, configuration: ModelConfiguration, URL storeURL: URL?, options: [AnyHashable: Any]?) throws -> NSPersistentStore { - var store: NSPersistentStore? - var storeError: NSError? - self.performSynchronously { + return try self.performSynchronously { do { - store = try self.addPersistentStore( + return try self.addPersistentStore( ofType: storeType, configurationName: configuration, at: storeURL, @@ -89,13 +87,8 @@ internal extension NSPersistentStoreCoordinator { } catch { - storeError = error as NSError + throw CoreStoreError(error) } } - if let store = store { - - return store - } - throw CoreStoreError(storeError) } } From d3b3b5ff4a02b6a5e36a0aad4bfc980d92cdcb20 Mon Sep 17 00:00:00 2001 From: John Rommel Estropia Date: Mon, 13 Nov 2017 02:44:26 +0900 Subject: [PATCH 2/6] added fake progress for lightweight migrations --- Sources/DataStack+Migration.swift | 33 ++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/Sources/DataStack+Migration.swift b/Sources/DataStack+Migration.swift index 0a19091..292bdb1 100644 --- a/Sources/DataStack+Migration.swift +++ b/Sources/DataStack+Migration.swift @@ -687,8 +687,35 @@ public extension DataStack { do { + let timerQueue = DispatchQueue( + label: "DataStack.lightweightMigration.timerQueue", + qos: .utility, + attributes: [] + ) + let estimatedTime: TimeInterval = 60 * 3 // 3 mins + let interval: TimeInterval = 1 + let fakeTotalUnitCount: Float = 0.9 * Float(progress.totalUnitCount) + var fakeProgress: Float = 0 + + var recursiveCheck: () -> Void = {} + recursiveCheck = { + + guard fakeProgress < 1 else { + + return + } + progress.completedUnitCount = Int64(fakeTotalUnitCount * fakeProgress) + fakeProgress += Float(interval / estimatedTime) + + timerQueue.asyncAfter( + deadline: .now() + interval, + execute: recursiveCheck + ) + } + timerQueue.async(execute: recursiveCheck) + _ = try withExtendedLifetime(NSPersistentStoreCoordinator(managedObjectModel: destinationModel)) { (coordinator: NSPersistentStoreCoordinator) in - + try coordinator.addPersistentStoreSynchronously( type(of: storage).storeType, configuration: storage.configuration, @@ -698,6 +725,10 @@ public extension DataStack { ) ) } + timerQueue.sync { + + fakeProgress = 1 + } _ = try? storage.cs_finalizeStorageAndWait(soureModelHint: destinationModel) progress.completedUnitCount = progress.totalUnitCount return From 2c7039232eeb1548951d1672ba441646c3a1808b Mon Sep 17 00:00:00 2001 From: John Rommel Estropia Date: Wed, 15 Nov 2017 23:50:10 +0900 Subject: [PATCH 3/6] merge sqlite journal files before migration --- Sources/DataStack+Migration.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/DataStack+Migration.swift b/Sources/DataStack+Migration.swift index 292bdb1..f723670 100644 --- a/Sources/DataStack+Migration.swift +++ b/Sources/DataStack+Migration.swift @@ -714,6 +714,7 @@ public extension DataStack { } timerQueue.async(execute: recursiveCheck) + _ = try storage.cs_finalizeStorageAndWait(soureModelHint: sourceModel) _ = try withExtendedLifetime(NSPersistentStoreCoordinator(managedObjectModel: destinationModel)) { (coordinator: NSPersistentStoreCoordinator) in try coordinator.addPersistentStoreSynchronously( From 18b933957e0e5024cf3888ffa2ddc46da3065bf6 Mon Sep 17 00:00:00 2001 From: John Rommel Estropia Date: Thu, 16 Nov 2017 02:28:18 +0900 Subject: [PATCH 4/6] version bump --- CoreStore.podspec | 2 +- Sources/Info.plist | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CoreStore.podspec b/CoreStore.podspec index 61f6a55..30db46f 100644 --- a/CoreStore.podspec +++ b/CoreStore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "CoreStore" - s.version = "4.2.3" + s.version = "4.2.4" s.license = "MIT" s.summary = "Unleashing the real power of Core Data with the elegance and safety of Swift" s.homepage = "https://github.com/JohnEstropia/CoreStore" diff --git a/Sources/Info.plist b/Sources/Info.plist index e07b407..bd54e0e 100644 --- a/Sources/Info.plist +++ b/Sources/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 4.2.3 + 4.2.4 CFBundleSignature ???? CFBundleVersion From 583c6b7249bcd038578b21b0d6677d14e52b9ceb Mon Sep 17 00:00:00 2001 From: John Rommel Estropia Date: Sun, 19 Nov 2017 13:49:21 +0900 Subject: [PATCH 5/6] minor code cleanup --- Sources/DataStack+Migration.swift | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Sources/DataStack+Migration.swift b/Sources/DataStack+Migration.swift index f723670..ec7c849 100644 --- a/Sources/DataStack+Migration.swift +++ b/Sources/DataStack+Migration.swift @@ -682,6 +682,15 @@ public extension DataStack { private func startMigrationForStorage(_ storage: T, sourceModel: NSManagedObjectModel, destinationModel: NSManagedObjectModel, mappingModel: NSMappingModel, migrationType: MigrationType, progress: Progress) throws { + do { + + try storage.cs_finalizeStorageAndWait(soureModelHint: sourceModel) + } + catch { + + throw CoreStoreError(error) + } + let fileURL = storage.fileURL if case .lightweight = migrationType { @@ -714,7 +723,6 @@ public extension DataStack { } timerQueue.async(execute: recursiveCheck) - _ = try storage.cs_finalizeStorageAndWait(soureModelHint: sourceModel) _ = try withExtendedLifetime(NSPersistentStoreCoordinator(managedObjectModel: destinationModel)) { (coordinator: NSPersistentStoreCoordinator) in try coordinator.addPersistentStoreSynchronously( @@ -730,13 +738,13 @@ public extension DataStack { fakeProgress = 1 } - _ = try? storage.cs_finalizeStorageAndWait(soureModelHint: destinationModel) + try storage.cs_finalizeStorageAndWait(soureModelHint: destinationModel) progress.completedUnitCount = progress.totalUnitCount return } catch { - // try manual migration + throw CoreStoreError(error) } } @@ -764,7 +772,6 @@ public extension DataStack { do { - try storage.cs_finalizeStorageAndWait(soureModelHint: sourceModel) try migrationManager.migrateStore( from: fileURL, sourceType: type(of: storage).storeType, From 15e5e4fdf62bf64d9a044b28ac80f8d9c76b3cda Mon Sep 17 00:00:00 2001 From: John Rommel Estropia Date: Sun, 19 Nov 2017 15:34:09 +0900 Subject: [PATCH 6/6] delete shm file after converting to DELETE journal mode --- Sources/SQLiteStore.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/SQLiteStore.swift b/Sources/SQLiteStore.swift index be95dfb..7abebde 100644 --- a/Sources/SQLiteStore.swift +++ b/Sources/SQLiteStore.swift @@ -219,6 +219,7 @@ public final class SQLiteStore: LocalStorage { options: [NSSQLitePragmasOption: ["journal_mode": "DELETE"]] ) } + _ = try? FileManager.default.removeItem(atPath: "\(self.fileURL.path)-shm") } /**