Skip to content

Commit 1f4f9a7

Browse files
authored
Fix database migration issue with different database models (#20217)
2 parents 407ff3f + f353613 commit 1f4f9a7

File tree

2 files changed

+49
-35
lines changed

2 files changed

+49
-35
lines changed

WordPress/Classes/Utility/ContextManager.swift

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,41 @@ public class ContextManager: NSObject, CoreDataStack, CoreDataStackSwift {
135135
save(context, .asynchronously)
136136
}
137137
}
138+
139+
static func migrateDataModelsIfNecessary(storeURL: URL, objectModel: NSManagedObjectModel) throws {
140+
guard FileManager.default.fileExists(atPath: storeURL.path) else {
141+
DDLogInfo("No store exists at \(storeURL). Skipping migration.")
142+
return
143+
}
144+
145+
guard let metadata = try? NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, at: storeURL),
146+
!objectModel.isConfiguration(withName: nil, compatibleWithStoreMetadata: metadata)
147+
else {
148+
return
149+
}
150+
151+
DDLogWarn("Migration required for persistent store.")
152+
153+
guard let modelFileURL = Bundle.main.url(forResource: "WordPress", withExtension: "momd") else {
154+
fatalError("Can't find WordPress.momd")
155+
}
156+
157+
guard let versionInfo = NSDictionary(contentsOf: modelFileURL.appendingPathComponent("VersionInfo.plist")) else {
158+
fatalError("Can't get the object model's version info")
159+
}
160+
161+
guard let modelNames = (versionInfo["NSManagedObjectModel_VersionHashes"] as? [String: AnyObject])?.keys else {
162+
fatalError("Can't parse the model versions")
163+
}
164+
165+
let sortedModelNames = modelNames.sorted { $0.compare($1, options: .numeric) == .orderedAscending }
166+
try CoreDataIterativeMigrator.iterativeMigrate(
167+
sourceStore: storeURL,
168+
storeType: NSSQLiteStoreType,
169+
to: objectModel,
170+
using: sortedModelNames
171+
)
172+
}
138173
}
139174

140175
// MARK: - Private methods
@@ -236,40 +271,6 @@ private extension ContextManager {
236271
return persistentContainer
237272
}
238273

239-
static func migrateDataModelsIfNecessary(storeURL: URL, objectModel: NSManagedObjectModel) throws {
240-
guard FileManager.default.fileExists(atPath: storeURL.path) else {
241-
DDLogInfo("No store exists at \(storeURL). Skipping migration.")
242-
return
243-
}
244-
245-
guard let metadata = try? NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, at: storeURL),
246-
objectModel.isConfiguration(withName: nil, compatibleWithStoreMetadata: metadata)
247-
else {
248-
return
249-
}
250-
251-
DDLogWarn("Migration required for persistent store.")
252-
253-
guard let modelFileURL = Bundle.main.url(forResource: "WordPress", withExtension: "momd") else {
254-
fatalError("Can't find WordPress.momd")
255-
}
256-
257-
guard let versionInfo = NSDictionary(contentsOf: modelFileURL.appendingPathComponent("VersionInfo.plist")) else {
258-
fatalError("Can't get the object model's version info")
259-
}
260-
261-
guard let modelNames = (versionInfo["NSManagedObjectModel_VersionHashes"] as? [String: AnyObject])?.keys else {
262-
fatalError("Can't parse the model versions")
263-
}
264-
265-
let sortedModelNames = modelNames.sorted { $0.compare($1, options: .numeric) == .orderedAscending }
266-
try CoreDataIterativeMigrator.iterativeMigrate(
267-
sourceStore: storeURL,
268-
storeType: NSSQLiteStoreType,
269-
to: objectModel,
270-
using: sortedModelNames
271-
)
272-
}
273274
}
274275

275276
extension ContextManager {

WordPress/Classes/Utility/CoreDataHelper.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,14 +250,19 @@ extension CoreDataStack {
250250
throw ContextManager.ContextManagerError.missingDatabase
251251
}
252252

253+
try? migrateDatabaseIfNecessary(at: databaseLocation)
254+
253255
mainContext.reset()
254256
try storeCoordinator.remove(store)
255257
let databaseReplaced = replaceDatabase(from: databaseLocation, to: currentDatabaseLocation)
256258

257259
do {
260+
let options = [NSMigratePersistentStoresAutomaticallyOption: true,
261+
NSInferMappingModelAutomaticallyOption: true]
258262
try storeCoordinator.addPersistentStore(ofType: NSSQLiteStoreType,
259263
configurationName: nil,
260-
at: currentDatabaseLocation)
264+
at: currentDatabaseLocation,
265+
options: options)
261266

262267
if databaseReplaced {
263268
// The database was replaced successfully and the store added with no errors so we
@@ -327,4 +332,12 @@ extension CoreDataStack {
327332
_ = try? FileManager.default.replaceItemAt(locationShm, withItemAt: shmBackup)
328333
_ = try? FileManager.default.replaceItemAt(locationWal, withItemAt: walBackup)
329334
}
335+
336+
private func migrateDatabaseIfNecessary(at databaseLocation: URL) throws {
337+
guard let modelFileURL = Bundle.main.url(forResource: "WordPress", withExtension: "momd"),
338+
let objectModel = NSManagedObjectModel(contentsOf: modelFileURL) else {
339+
return
340+
}
341+
try ContextManager.migrateDataModelsIfNecessary(storeURL: databaseLocation, objectModel: objectModel)
342+
}
330343
}

0 commit comments

Comments
 (0)