NSPersistentStoreCoordinator.migratePersistentStore - можно ли ускорить работу? - PullRequest
0 голосов
/ 16 июня 2019

В моем проекте мне нужна возможность создать резервную копию базы данных, поэтому в соответствии с этим блогом я создал NSPersistentStoreCoordinator расширение:

import Foundation
import CoreData

extension NSPersistentStoreCoordinator {

    /// Safely copies the specified `NSPersistentStore` to a file.
    ///
    /// Credits: https://oleb.net/blog/2018/03/core-data-sqlite-backup/
    func backupPersistentStore(atIndex index: Int) throws {
        // Inspiration: https://stackoverflow.com/a/22672386
        // Documentation for NSPersistentStoreCoordinate.migratePersistentStore:
        // "After invocation of this method, the specified [source] store is
        // removed from the coordinator and thus no longer a useful reference."
        // => Strategy:
        // 1. Create a new "intermediate" NSPersistentStoreCoordinator and add
        //    the original store file.
        // 2. Use this new PSC to migrate to a new file URL.
        // 3. Drop all reference to the intermediate PSC.
        let sourceStore = persistentStores[index]
        let backupCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel)

        let intermediateStoreOptions = (sourceStore.options ?? [:]).merging(
            [NSReadOnlyPersistentStoreOption: true],
            uniquingKeysWith: { $1 }
        )
        let intermediateStore = try backupCoordinator.addPersistentStore(
            ofType: sourceStore.type,
            configurationName: sourceStore.configurationName,
            at: sourceStore.url,
            options: intermediateStoreOptions
        )

        let backupStoreOptions: [AnyHashable: Any] = [
            NSReadOnlyPersistentStoreOption: true,
            // Disable write-ahead logging. Benefit: the entire store will be
            // contained in a single file. No need to handle -wal/-shm files.
            // https://developer.apple.com/library/content/qa/qa1809/_index.html
            NSSQLitePragmasOption: ["journal_mode": "DELETE"],
            // Minimize file size
            NSSQLiteManualVacuumOption: true,
        ]
        let backupUrl = try prepareBackupUrl()

        try backupCoordinator.migratePersistentStore(
            intermediateStore,
            to: backupUrl,
            options: backupStoreOptions,
            withType: NSSQLiteStoreType
        )
    }

    /// Remeber to reload persistent stores if you using `NSPersistentContainer`
    /// `NSPersistentContainer.loadPersistentStores`
    func restorePersistentStore(atIndex index: Int) throws {
        let sourceStore = persistentStores[index]
        let sourceStoreUrl = sourceStore.url!
        let backupUrl = backupFileUrl()

        try replacePersistentStore(
            at: sourceStoreUrl,
            destinationOptions: nil,
            withPersistentStoreFrom: backupUrl,
            sourceOptions: nil,
            ofType: NSSQLiteStoreType
        )
    }
}

К сожалению, когда база данных огромна, migratePersistentStore работает очень долго. Я ищу некоторые улучшения, чтобы ускорить процесс.

Я не знаком с NSPersistentContainer.migratePersistentStore параметрами. После дня исследований я решил обратиться за помощью сюда.

Возможно NSSQLiteManualVacuumOption не обязательно. Возможно, другие варианты помогут мне.

Моя цель: Ускорить migratePersistentStore. Сохраните возможность восстановить Core Date из созданной резервной копии, используя replacePersistentStore.

Спасибо за любой совет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...