Хорошая схема для удаления файла базы данных в SQLiteOpenHelper.onDowngrade()

У меня есть существующая база данных, основанная на SQLiteOpenHelper, которая имеет несколько версий и код для ее обновления, и она отлично работает. Но в случае, если пользователь устанавливает более старую версию приложения (которое ожидает более низкую версию базы данных), оно в настоящее время аварийно завершает работу - ContentProvider, использующий его, не может получить доступ к базе данных. происходит сбой, но я не хочу на самом деле понижать версию базы данных - добавление кода для этого будет болезненным. Удаление всех таблиц, безусловно, сработает, но начинать с нового файла будет чище и менее подвержено ошибкам.

Вот о чем помощник базы данных выглядит так — ничего особенного

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.
    }
}

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

  • Делайте это извне: перехватывайте исключения в ContentProvider, удаляйте файл и запрашивайте снова откройте базу данных - Мне это не нравится, так как это не входит в обязанности провайдера.
  • Замена SQLiteOpenHelperмоей собственной копией этого класса, который удаляет файл вместо вызова onDowngrade. Проблема в том, что он использует закрытые части пакета SQLiteDatabase( например, .lock()), который я не могу заменить без дублирования SQLiteDatabase(это, вероятно, приведет к дублированию всего стека sqlite).

Есть ли хороший способ сделать это, или мне нужно пойти по пути DROP TABLES, например. как описано здесь?

6
задан Community 23 May 2017 в 11:52
поделиться