2012-03-20 1 views
6

SQLiteOpenHelperに基づいてデータベースを更新していますが、それをアップグレードするにはいくつかのバージョンとコードがあり、正常に動作します。しかし、ユーザーが古いバージョンのアプリケーションをインストールした場合(低いデータベースバージョンが必要な場合)、クラッシュする可能性があります。ContentProviderは、データベースにアクセスできません。私はそれがクラッシュするのを防ぎたいのですが、実際にはデータベースをダウングレードしたくありません。それを行うためのコードを追加することは苦労でしょう。すべてのテーブルを削除することは間違いなく機能しますが、新しいファイルから始めることは、より洗練されたエラーの発生が少ないことです。SQLiteOpenHelper.onDowngrade()のデータベースファイルを削除するためのスキーマが良好です

  • は外からそれを実行します:キャッチ例外で
    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、ファイルを削除し、データベースを再度開くように要求します。 - それはプロバイダの責任ではないので、私はそれが好きではありません。代わりにonDowngrade呼び出しのファイルを削除し、そのクラスの私自身のコピーでSQLiteOpenHelperの交換

  • - 問題は、それは私があまりにもSQLiteDatabaseを複製せずに置き換えることはできませんSQLiteDatabase(例えば.lock())のパッケージプライベートの部分を使用してということです(それはおそらくしまいますsqliteスタック全体を複製する際に)。

これを行うには良い方法がありますか、またはDROP TABLESなどの方法で行ってください。 like here

答えて

9

SQLiteOpenHelperを拡張してうまく動作する方法を見つけました。MyDbHelperで行う必要があるのは、このクラスを拡張することです。

public abstract class DeletingSQLiteOpenHelper extends SQLiteOpenHelper { 
    private static final String TAG = DeletingSQLiteOpenHelper.class.getSimpleName(); 

    private final File mDatabaseFile; 

    public DeletingSQLiteOpenHelper(Context context, String name, CursorFactory factory, int version, 
      DatabaseErrorHandler errorHandler) { 
     super(context, name, factory, version, errorHandler); 
     mDatabaseFile = context.getDatabasePath(name); 
    } 

    public DeletingSQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) { 
     super(context, name, factory, version); 
     mDatabaseFile = context.getDatabasePath(name); 
    } 

    @Override 
    public synchronized SQLiteDatabase getWritableDatabase() { 
     try { 
      return super.getWritableDatabase(); 
     } catch (SQLiteDowngradeFailedException e) { 
      // that's our notification 
     } 

     // try to delete the file 
     mDatabaseFile.delete() 

     // now return a freshly created database 
     return super.getWritableDatabase(); 
    } 

    @Override 
    public final void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     // throwing a custom Exception to catch it in getWritableDatabase 
     throw new SQLiteDowngradeFailedException(); 
    } 

    // that's the exception 
    static class SQLiteDowngradeFailedException extends SQLiteException { 
     public SQLiteDowngradeFailedException() {} 

     public SQLiteDowngradeFailedException(String error) { 
      super(error); 
     } 
    } 
} 
関連する問題