Mam istniejącą bazę danych opartą na SQLiteOpenHelper
, która ma kilka wersji i kod do aktualizacji i działa dobrze. Ale w przypadku, gdy użytkownik zainstaluje starszą wersję aplikacji (która spodziewa się niższej wersji bazy danych), będzie się teraz zawieszał - przy użyciu tej funkcji nie będzie można uzyskać dostępu do bazy danych. Chciałbym zapobiec awariom, ale nie chcę obniżać wersji bazy danych - dodanie do tego kodu byłoby bolesne. Zrzucenie wszystkich tabel na pewno by działało, ale począwszy od świeżego pliku jest imo cleaner i mniej podatne na błędy.Dobry schemat usuwania pliku bazy danych w SQLiteOpenHelper.onDowngrade()
To o co pomocnik baza wygląda - nic specjalnego
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.
}
}
możliwych sposobów Doszedłem do nadrobienia, które:
- Zrób to z zewnątrz: wyjątki dotyczące połowów
ContentProvider
, usuń plik i żądanie ponownego otwarcia bazy danych. - Nie podoba mi się to, ponieważ nie jest to odpowiedzialność dostawcy. - Wymiana
SQLiteOpenHelper
z własną kopią tej klasy, które usuwa plik zamiast dzwonićonDowngrade
- Problem jest to, że za pomocą pakietu prywatnej częściSQLiteDatabase
(np.lock()
), których nie można zastąpić bez powielaniaSQLiteDatabase
zbyt (prawdopodobnie spowodowałoby w duplikowaniu całego stosu sqlite).
Czy jest to dobre podejście, czy muszę jechać drogą np. DROP TABLES
jak opisano here?