使用onUpgrade备份旧数据库,替换数据库并还原数据

时间:2012-06-14 04:21:33

标签: java android sqlite

在我的应用中,我通过assets文件夹提供最新版本的数据库。为简单起见,假设我的DB方案是PRIM KEY INTEGER _id,TEXT名称和INTEGER数量。数量是用户可以在应用程序中编辑的唯一内容,其他一切都是静态数据。数量默认为0。

以下是我目前正在尝试进行的升级:

1。)遍历所有表,找到数量> gt的条目。 0,并将这些条目存储在包含ID和Quantity值的对象列表中,以及原始表名称。

2.删除我刚刚通过

迭代的旧数据库

3.。)从包含更新的静态信息的资产中复制新数据库。

4。)迭代步骤1中的列表,并使用相应表格中的数量更新相应的ID。

这是我的onUpdate方法(titleArray是一个包含我的表名的字符串数组):

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    Log.w("TaskDBAdapter", "Upgrading from version " + oldVersion + " to " + newVersion);


    ArrayList<backupKey> bak = new ArrayList<backupKey>();

    Cursor cursor = null;
        for(int i = 0; i < titleArray.length; i++)
        {
             cursor = db.rawQuery("SELECT * FROM " + titleArray[i] + " WHERE quantity > 0", null);
             if (cursor.moveToFirst()){
                   do{
                       backupKey key = new backupKey(titleArray[i],
                               cursor.getInt(cursor.getColumnIndex("_id")),
                               cursor.getInt(cursor.getColumnIndex("quantity")));
                       bak.add(key);

                   }while(cursor.moveToNext());
                }

        }
        cursor.close();

        myContext.deleteDatabase(DB_NAME);

        try 
        {
            InputStream myInput = myContext.getAssets().open(DB_NAME);

            String outFileName = DB_PATH + DB_NAME;

            OutputStream myOutput = new FileOutputStream(outFileName, false);


            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer))>0){
                myOutput.write(buffer, 0, length);
            }

            myOutput.flush();
            myOutput.close();
            myInput.close();

        } catch (IOException e) 
        {
            Log.w("TaskDBAdapter", "failed");
            throw new Error("Error copying database");

        }

    for (int i = 0; i < bak.size(); i++)
    {

        ContentValues args = new ContentValues();
        args.put("quantity", bak.get(i).quantity);
        String where = "_id = ?";
        String[] whereArgs = {Integer.toString(bak.get(i).id)};
        db.update(bak.get(i).range, args, where, whereArgs);
    }

} //End of onUpgrade

我可以确认arraylist已成功填充了正确的数据。我之前试图覆盖数据库,但它似乎永远不会起作用。我不得不添加myContext.deleteDatabase(DB_NAME);在文件写入操作之前,要成功替换数据库。我可以确认我的最终更新迭代没有生成任何奇怪的数据 - 它具有正确的表名,ID和数量值。

问题是,我的onUpgrade后数量没有更新。静态数据更新为我已包含在资产文件夹中的最新版本,但数量数据未更新。这是因为我销毁了最初提供给方法的数据库(在这种情况下是“db”参数)?这甚至是参数是什么?如何在新数据库中更新数据?

另外:如果有更好的方法可以解决这个问题,我会全力以赴=)

1 个答案:

答案 0 :(得分:2)

onUpgarde()用于更新数据库结构(添加/重命名列等),而不是实际数据。第一次启动时,您可能希望在实际应用中执行此操作。此外,尝试升级用户输入的数据可能不是最好的主意。为什么不拥有两个表(或数据库) - 一个包含您提供的数据,另一个包含用户输入的数据?您只需复制用户编辑的行,并将原始数据保留为只读。