Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 35 additions & 34 deletions WordPress/Classes/Utility/ContextManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,41 @@ public class ContextManager: NSObject, CoreDataStack, CoreDataStackSwift {
save(context, .asynchronously)
}
}

static func migrateDataModelsIfNecessary(storeURL: URL, objectModel: NSManagedObjectModel) throws {
guard FileManager.default.fileExists(atPath: storeURL.path) else {
DDLogInfo("No store exists at \(storeURL). Skipping migration.")
return
}

guard let metadata = try? NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, at: storeURL),
!objectModel.isConfiguration(withName: nil, compatibleWithStoreMetadata: metadata)
Copy link
Contributor

@crazytonyli crazytonyli Feb 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦‍♂️ I mis-translated this line in #19770. Thanks for fixing this up. But I'm surprised the issue wasn't caught by the migration unit tests 🤔

Copy link
Contributor

@dvdchr dvdchr Feb 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, thank you for the quick response @crazytonyli ! I was just about to ping you to confirm if this change was intended.

else {
return
}

DDLogWarn("Migration required for persistent store.")

guard let modelFileURL = Bundle.main.url(forResource: "WordPress", withExtension: "momd") else {
fatalError("Can't find WordPress.momd")
}

guard let versionInfo = NSDictionary(contentsOf: modelFileURL.appendingPathComponent("VersionInfo.plist")) else {
fatalError("Can't get the object model's version info")
}

guard let modelNames = (versionInfo["NSManagedObjectModel_VersionHashes"] as? [String: AnyObject])?.keys else {
fatalError("Can't parse the model versions")
}

let sortedModelNames = modelNames.sorted { $0.compare($1, options: .numeric) == .orderedAscending }
try CoreDataIterativeMigrator.iterativeMigrate(
sourceStore: storeURL,
storeType: NSSQLiteStoreType,
to: objectModel,
using: sortedModelNames
)
}
}

// MARK: - Private methods
Expand Down Expand Up @@ -236,40 +271,6 @@ private extension ContextManager {
return persistentContainer
}

static func migrateDataModelsIfNecessary(storeURL: URL, objectModel: NSManagedObjectModel) throws {
guard FileManager.default.fileExists(atPath: storeURL.path) else {
DDLogInfo("No store exists at \(storeURL). Skipping migration.")
return
}

guard let metadata = try? NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, at: storeURL),
objectModel.isConfiguration(withName: nil, compatibleWithStoreMetadata: metadata)
else {
return
}

DDLogWarn("Migration required for persistent store.")

guard let modelFileURL = Bundle.main.url(forResource: "WordPress", withExtension: "momd") else {
fatalError("Can't find WordPress.momd")
}

guard let versionInfo = NSDictionary(contentsOf: modelFileURL.appendingPathComponent("VersionInfo.plist")) else {
fatalError("Can't get the object model's version info")
}

guard let modelNames = (versionInfo["NSManagedObjectModel_VersionHashes"] as? [String: AnyObject])?.keys else {
fatalError("Can't parse the model versions")
}

let sortedModelNames = modelNames.sorted { $0.compare($1, options: .numeric) == .orderedAscending }
try CoreDataIterativeMigrator.iterativeMigrate(
sourceStore: storeURL,
storeType: NSSQLiteStoreType,
to: objectModel,
using: sortedModelNames
)
}
}

extension ContextManager {
Expand Down
15 changes: 14 additions & 1 deletion WordPress/Classes/Utility/CoreDataHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -250,14 +250,19 @@ extension CoreDataStack {
throw ContextManager.ContextManagerError.missingDatabase
}

try? migrateDatabaseIfNecessary(at: databaseLocation)

mainContext.reset()
try storeCoordinator.remove(store)
let databaseReplaced = replaceDatabase(from: databaseLocation, to: currentDatabaseLocation)

do {
let options = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
try storeCoordinator.addPersistentStore(ofType: NSSQLiteStoreType,
configurationName: nil,
at: currentDatabaseLocation)
at: currentDatabaseLocation,
options: options)

if databaseReplaced {
// The database was replaced successfully and the store added with no errors so we
Expand Down Expand Up @@ -327,4 +332,12 @@ extension CoreDataStack {
_ = try? FileManager.default.replaceItemAt(locationShm, withItemAt: shmBackup)
_ = try? FileManager.default.replaceItemAt(locationWal, withItemAt: walBackup)
}

private func migrateDatabaseIfNecessary(at databaseLocation: URL) throws {
guard let modelFileURL = Bundle.main.url(forResource: "WordPress", withExtension: "momd"),
let objectModel = NSManagedObjectModel(contentsOf: modelFileURL) else {
return
}
try ContextManager.migrateDataModelsIfNecessary(storeURL: databaseLocation, objectModel: objectModel)
}
}