Tôi có một cơ sở dữ liệu hiện có dựa trên SQLiteOpenHelper
có một số phiên bản và mã để nâng cấp nó và hoạt động tốt. Nhưng trong trường hợp người dùng cài đặt phiên bản cũ hơn của ứng dụng (dự kiến phiên bản cơ sở dữ liệu thấp hơn) thì hiện tại nó sẽ bị lỗi - số ContentProvider
sử dụng nó không thể truy cập cơ sở dữ liệu. Tôi muốn ngăn chặn nó bị rơi nhưng tôi không muốn hạ cấp cơ sở dữ liệu - việc thêm mã để làm điều đó sẽ là đau đớn. Rơi tất cả các bảng chắc chắn sẽ làm việc nhưng bắt đầu với một tập tin mới là imo sạch hơn và ít bị lỗi.Giản đồ tốt để xóa tệp cơ sở dữ liệu trong SQLiteOpenHelper.onDowngrade()
Đó là về những gì các helper cơ sở dữ liệu trông giống như - không có gì đặc biệt
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.
}
}
Các cách có thể tôi đã đi lên để làm điều đó là:
- làm nó từ bên ngoài: ngoại lệ catch trong
ContentProvider
, xóa tệp và yêu cầu mở lại cơ sở dữ liệu. - Tôi không thích điều đó vì nó không phải là trách nhiệm của nhà cung cấp. - Thay
SQLiteOpenHelper
với bản sao của riêng tôi của lớp đó mà xóa các tập tin thay vì gọionDowngrade
- Vấn đề là nó sử dụng bộ phận kín góiSQLiteDatabase
(ví dụ.lock()
) mà tôi không thể thay thế mà không trùng lặpSQLiteDatabase
quá (mà có lẽ sẽ cho kết quả sao chép toàn bộ ngăn xếp sqlite).
Có cách nào tốt để làm điều đó hay tôi phải đi theo cách DROP TABLES
ví dụ: như mô tả here?