deleteDatabase() does not delete journal files on iOS
Opened this issue · 0 comments
I know this module isn't really being maintained anymore, but thought people should know...
If you're trying to delete your database in order to replace it with a new one, iOS may give you a database corrupt
error when you try to open the new one.
Specifically: On iOS calling this module's deleteDatabase("yourDbName")
method will delete the database file, but will not delete its accomapying journal file(s) and other temporary files.
Expected Behavior
deleteDatabase("yourDbName")
should also delete any database journal files. The possible files depend on the database's PRAGMA journal_mode
...
- If the
journal_mode
is set to "journal" then there may be fileyourDbName-journal
- If the
journal mode
is "wal" then there may be filesyourDbName-wal
andyourDbName-shm
According to the SQLite docs there may be other temporary database files.
Current Behavior
In the module's Andriod native code all database files seem to be deleted using the system API, but on iOS the module's native code is just deleting the main database file. Journal files are left in place.
Possible Solutions
-
In RN JavaScript we could delete any database files before opening our replacement database with
SQLite.openDatabase()
. It may not be easy to find them all, since the docs say there are nine kinds of temporary files, and it doesn't give precise filenames for some of them. Butjournal
,wal
andshm
files are easily located though. Deleting these may be enough for most use-cases. -
A more reliable solution: Maybe iOS has a SQLite API method similar to Android's
android.database.sqlite.SQLiteDatabase.deleteDatabase()
?
I can't find any docs whatsoever on iOSsqlite3
API for obj-c, but it it appears to follow the SQLite C interface. It looks like resetting the database is a way of removing temporary files. -
Perhaps it can be done in JavaScript with:
open db → vacuum db → close db → delete database file
Steps to Reproduce
- Open your react-native app on iOS
- Open database with
const db = await SQLiteStorage.openDatabase(dbName)
- Close database with
await db.close()
. The journal file(s) should now be there beside the main db file. - Delete database with
const deleteResult = await SQLiteStorage.deleteDatabase(dbName)
- Get a folder listing of the database folder. On iOS the journal files will still be there. On Android they'll be gone.
Context
After an app update our app often needs to replace a database during the app's startup. When we do this on iOS we sometimes get a database corrupt
error in the XCode console. The problem is resolved when we manually delete the old journal files before opening the new database (although this might not be 100% reliable).
Your Environment
- SQLite PRAGMA journal_mode: "wal"
- React Native SQLite Storage Version used: 6.0.1
- React Native version used: 66.5
- Operating System and version (simulator or device): iPhone 8 (iOS 16.7.10), iPhone 13 Pro (iOS 18.1.1)
- IDE used: XCode