I have an existing database based on SQLiteOpenHelper
that has several versions and code to upgrade it and that works fine. But in case a user installs an older version of the app (that expects a lower database version) it will currently crash - the ContentProvider
using it can't access the database. I'd like to prevent it from crashing but I don't want to actually downgrade the database - adding the code to do that would be pain. Dropping all tables would certainly work but starting with a fresh file is imo cleaner and less error prone.
That's about what the database helper looks like - nothing special
public class MyDbHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 3;
private static final String DATABASE_NAME = "my.db";
public MyDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
onUpgrade(db, 0, DATABASE_VERSION);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion < 1) db.execSQL("CREATE TABLE A...");
if (newVersion < 2) db.execSQL("CREATE TABLE B...");
if (newVersion < 3) db.execSQL("CREATE TABLE C...");
}
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// I'd like to delete the database here
// the only problem is that I can't from here
// since this is called in the middle of getWritableDatabase()
// and SQLiteDatabase has no .recreate() method.
}
}
The possible ways I've come up to do that are:
- Do it from the outside: catch exceptions in the
ContentProvider
, delete the file and request to open the database again. - I don't like that since it's not the responsibility of the provider. - Replacing
SQLiteOpenHelper
with my own copy of that class that deletes the file instead of callingonDowngrade
- Problem is that it's using package private parts ofSQLiteDatabase
(e.g..lock()
) which I can't replace without duplicatingSQLiteDatabase
too (that would probably result in duplicating the whole sqlite stack).
Is there any good approach to do that or do I have to go the DROP TABLES
way e.g. like described here?