开发者

What triggers SqliteDbOpenHelper onUpgrade()?

开发者 https://www.devze.com 2023-04-11 02:37 出处:网络
Can someone explain how the onUpgrade function is called within the SqliteDbOpenHelper class. I\'m opening my database but it\'s not calling the onUpgrade even though I\'ve changed the DB_VERSION.

Can someone explain how the onUpgrade function is called within the SqliteDbOpenHelper class. I'm opening my database but it's not calling the onUpgrade even though I've changed the DB_VERSION.

See following code:

public class DbHelper extends SQLiteOpenHelper {
    private static final String TAG = "DbHelper";

    static final String DB_NAME = "caddata.sqlite";
    static final int DB_VERSION = 4;

    private static String DB_PATH = "";
    private Context myContext;
    private SQLiteDatabase myDataBase;

    public DbHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
        this.myContext = context;

        DB_PATH = "/data/data/"
                + context.getApplicationContext().getPackageName()
                + "/databases/";            
    }

    public DbHelper open() throws SQLException {        
        myDataBase =  getWritableDatabase();

        Log.d(TAG, "DbHelper Opening Version: " +  this.myDataBase.getVersion());
        return this;
    }

    @Override
    public synchronized void close() {

        if (myDataBase != null)
            myDataBase.close();

        super.close();

    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        Log.d(TAG, "onCreate called");

        try {           
            createDataBase();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if ( newVersion > oldVersion)
        {
            Log.d(TAG, "New database version exists for upgrade.");         
            try {
                Log.d(TAG, "Copying database...");
                copyDataBase();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }       
        }
    }

    public void createDataBase() throws IOException {

        boolean dbExist = checkDataBase();

        if (!dbExist) {         

            try {
                copyDataBase();
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }

        openDataBaseForRead();
    }


    private boolean checkDataBase() {

        SQLiteDatabase checkDB = null;

        try {
            String myPath = DB_PATH + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READONLY
                            | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
            Log.d(TAG, "db exists");
        } catch (SQLiteException e) {
            // database does't exist yet.
            Log.d(TAG, "db doesn't exist");

        }

        if (checkDB != null) {
            checkDB.close();            
        }

        return checkDB != null ? true : false;
    }


    private void copyDataBase() throws IOException {

        // Open your local db as the input stream
        InputStream myInput = myContext.getAssets().open(DB_NAME);

        // Path to the just created empty db
        String outFileName = DB_PATH + DB_NAME;

        // Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(outFileName);

        // transfer bytes from the inputfile to the outputfile
        byte[] buffer = new byte[2048];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }

        // Close the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();

        myDataBase.setVersion(DB_VERSION);
    }

    public void openDataBaseForRead() throws SQLException {

        // Open the database
        String myPath = DB_PATH + DB_NAME;      
        myDataBase = SQLiteDatabase.openDatabase(myPath, null,  SQLiteDatabase.OPEN_READONLY);
    }

    public void openDataBaseForWrite() throws SQLException {

        // Open the database
        S开发者_开发技巧tring myPath = DB_PATH + DB_NAME;      
        myDataBase = SQLiteDatabase.openDatabase(myPath, null,  SQLiteDatabase.OPEN_READWRITE | SQLiteDatabase.NO_LOCALIZED_COLLATORS );
    }


}

Also see my question detailed here: Why is onUpgrade() not being invoked on Android sqlite database? for which I didn't get a response.

My main activity opens the database from the helper. It was my assumption that just opening the database will cause onUpgrade() function to be called:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        DbHelper myDbHelper =  new DbHelper(this);

        try {

            myDbHelper.createDataBase();

        } catch (IOException ioe) {

            throw new Error("Unable to create database");

        }

        try {

            myDbHelper.openDataBaseForRead();

        }catch(SQLException sqle){

            throw sqle;

        }
}


In my opinion, the onCreate() and onUpgrade() function work only when you open a database with the SQLiteOpenHelper. that means you should call the function getWritableDatabase() or getReadbleDatabase() to open the database and then maybe it can works normally.


(Updated after Chris's comment) Pure logic suggests that DB must be upgraded each time it opens with a greater version. Never checked this case, but, as far as I know, onUpgrade() is always invoked during application upgrade when database version has been changed.


SQLlite database files have an internal version #. If the API tries to open an existing file and the version is less than some specified one, onUpgrade is called so you can handle it.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号