iosswiftcorestore

Move CoreStore SQLiteStore to another location


In my app using CoreStore 5.3, I am trying to move my local sqlite storage to another location to be able to access the database from an app extension. While moving the files using FileManager.default.moveItem(at: oldURL, to: newURL) for the currently 3 files (MyApp.sqlite, MyApp.sqlite-wal and MyApp.sqlite-shm) works fine, I just dont think it is a good idea to do this ...

if FileManager.default.fileExists(atPath: oldFileURL.path) {
    do {
        try FileManager.default.moveItem(at: oldFileURL, to: newFileURL)
        try FileManager.default.moveItem(at: oldJournalingURL, to: journalingURL)
        try FileManager.default.moveItem(at: oldSharedMemoryURL, to: sharedMemoryURL)
    } catch let error {
        // error handling ...
    }
}

I know there is the functionality on the NSPersistentStoreCoordinator to migratePersistentStore (https://developer.apple.com/documentation/coredata/nspersistentstorecoordinator/1468927-migratepersistentstore)

So you would normally do this for example:

if let persistentStore = persistentStoreCoordinator.persistentStores.first {
    do {
        try persistentStoreCoordinator.migratePersistentStore(persistentStore, to: newFileURL, options: nil, withType: NSSQLiteStoreType)
    } catch {
        print("error")
    }
}

... as this also moves all the associated files.

However, apparently this method is not exposed in CoreStore. As well as the persistentStoreCoordinator being an internal property of the DataStack, the only way to access it is through unsafeContext(), after the dataStack has already been set up, but that would cause more trouble because the context then tries do do save(), which wont work as the persistent store has been moved.

Is there any other way of doing this with CoreStore?


Solution

  • You are right that there is currently no way to do this from CoreStore. Part of the reason is that there is really no way to do this safely. There is no way for CoreStore to know that none of the mentioned files are being used somewhere else before moving them.

    For SQLite stores, moving the 3 files you have mentioned will likely be the simplest implementation. If you are using "External Storage" for binary attributes, you will also want to move the folder named .<sqlitename>_SUPPORT. So if your sqlite file is named mydata.sqlite, this folder will be named .mydata_SUPPORT.

    My advice is to create a dedicated folder for your store and put only the SQLite-related files there. So next time you will want to move directories you only need to move the folder itself.