On Android, when an app rolls back or manually loads an older version of the app with an older database version, this error occurs:
Fatal Exception: android.database.sqlite.SQLiteException: Can't downgrade database from version 5 to 4
at androidx.sqlite.db.SupportSQLiteOpenHelper$Callback.onDowngrade(SupportSQLiteOpenHelper.java:201)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onDowngrade(FrameworkSQLiteOpenHelper.java:144)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:255)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:96)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:54)
at com.squareup.sqldelight.android.AndroidSqliteDriver$database$2.invoke(AndroidSqliteDriver.java:30)
at com.squareup.sqldelight.android.AndroidSqliteDriver$database$2.invoke(AndroidSqliteDriver.java:19)
This crashes the app and opens the screen to the app settings screen, and the user is unable to use the app until the user wipes app data via the settings screen. If I want to avoid that scenario, I have to write my own data integrity function that runs before any database operations and wipes the data if necessary.
If there is an easier way to do this I'd love to know. I'm not even sure if that's something I can do via SqlDelight right now.
It would be useful to have a "wipe data upon OnDowngrade" configuration setting, or any other easy way to set up default actions for certain exceptions.
I considered asking for such a feature myself.
I only need that for development so I would enable that only in debug.
Scenario (Android app):
adb shell pm clear packagename as it is faster than clicking through settings.Currently we use database mostly for a network cache so clearing database if there are any incompatibilities of schema with sqlite file works fine for us.
I once asked for a destructive migration(mainly for development purpose), and the recommendation at that time was in-memory db.
That link gave me a better answer.
I feel dumb for not seeing this before, but when instantiating your Database, you pass AndroidSqliteDriver into the constructor. AndroidSqliteDriver takes a callback which handles OnDowngrade, among other things. I'll attempt a solution via that method.
If it works and I'm sure I understand the process, I'll put in a PR for documentation update. I guess it'll go under migration 馃
Most helpful comment
That link gave me a better answer.
I feel dumb for not seeing this before, but when instantiating your Database, you pass AndroidSqliteDriver into the constructor. AndroidSqliteDriver takes a callback which handles OnDowngrade, among other things. I'll attempt a solution via that method.
If it works and I'm sure I understand the process, I'll put in a PR for documentation update. I guess it'll go under migration 馃