2012-06-14 5 views
1

В моем приложении я загружаю самую последнюю версию моей базы данных через папку с ресурсами. Для простоты, скажем, моя схема БД - это PRIM KEY INTEGER _id, имя TEXT и количество INTEGER. Количество - это единственное, что пользователь может редактировать в приложении, все остальное - это статические данные. Количество по умолчанию в 0.Использование onUpgrade для резервного копирования старой базы данных, замены базы данных и восстановления данных

Вот что я в настоящее время пытается сделать onUpgrade:

1.) Перебрать все таблицы, найти записи, которые имеют величину> 0, и хранить эти записи в список объектов, содержащих значения ID и количества, а также имя исходной таблицы.

2.) Удалить старую базу данных, что я просто итерированным через

3.) Скопируйте новую базу данных из активов, который содержит обновленные статическую информацию.

4.) Перейдите через список с шага 1 и обновите соответствующие идентификаторы количествами в соответствующих таблицах.

Вот мой 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); прежде чем операция записи файла для базы данных будет успешно заменена. Я могу подтвердить, что моя последняя итерация обновления не создает каких-либо странных данных - она ​​имеет правильные значения для имени таблицы, идентификатора и количества.

Проблема в том, что количество не обновляется после моего onUpgrade. Статические данные обновляются до последней версии, включенной в папку моих ресурсов, но данные количества не обновляются. Это потому, что я уничтожил базу данных, первоначально предоставленную методу (в этом случае параметр «db»)? Это даже то, что параметр? Как я могу получить данные в новой базе данных?

также: Если есть лучший способ пойти об этом, я все уши =)

ответ

2

onUpgarde() предназначен для обновления структуры базы данных (добавление/переименование столбцов, и т.д.), а не фактические данные. Возможно, вы захотите сделать это в реальном приложении при первом запуске. Кроме того, попытка обновления введенных пользователем данных может оказаться не лучшей идеей. Почему бы не иметь две таблицы (или даже базы данных) - одну с данными, которые вы поставляете, и одну с введенными пользователем данными? Вы можете просто скопировать строки, которые редактируете пользователи, и оставить исходные данные только для чтения.

+0

Я думал, что это было для обновления структуры, но в моем предыдущем вопросе здесь я слышал, что это подходящее место для обработки обновлений данных, а также обновлений схемы ... Ну, это бросает ключ в мой планы – Brett

+0

Cf. справочные документы: «Вызывается, когда необходимо обновить базу данных. Реализация должна использовать этот метод, чтобы отбрасывать таблицы, добавлять таблицы или делать что-то еще, что необходимо для обновления до новой версии схемы ». Вы, конечно же, могли бы что-либо сделать, но так как это называется автоматически, когда приложение сначала использует БД, у вас нет большого контроля над ним. Если вам необходимо выполнить длительное обновление данных, вы должны уведомить пользователя (и, возможно, дать им варианты) об этом, когда приложение находится в стабильном состоянии. –

Смежные вопросы