Ho un database esistente basato su SQLiteOpenHelper
che ha diverse versioni e codice per aggiornarlo e funziona perfettamente. Ma nel caso in cui un utente installa una versione precedente dell'app (che si aspetta una versione di database inferiore) si bloccherà in questo momento - il ContentProvider
che lo utilizza non può accedere al database. Mi piacerebbe impedirgli di andare in crash, ma non voglio in realtà effettuare il downgrade del database - aggiungere il codice per farlo sarebbe doloroso. Eliminare tutte le tabelle funzionerebbe sicuramente, ma iniziare con un nuovo file è più pulito e meno incline agli errori.Buono schema per eliminare il file di database in SQLiteOpenHelper.onDowngrade()
Questo è su ciò che l'aiutante di database sembra - niente di speciale
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.
}
}
I modi possibili sono venuto fino a farlo sono:
- farlo dal di fuori: eccezioni di cattura in
ContentProvider
, eliminare il file e richiedere nuovamente l'apertura del database. - Non mi piace perché non è responsabilità del provider. - Sostituzione
SQLiteOpenHelper
con la mia copia di quella classe che elimina il file invece di chiamareonDowngrade
- Il problema è che si tratta di utilizzo dei pacchetti parti intimeSQLiteDatabase
(ad es.lock()
) che non può sostituire senza duplicareSQLiteDatabase
troppo (che sarebbe probabilmente avvenuta nel duplicare l'intero stack sqlite).
C'è un buon approccio per farlo o devo andare al modo DROP TABLES
ad es. come descritto here?