2016-05-05 5 views
1

В моем приложении пользователь может экспортировать и импортировать свой файл базы данных для резервного копирования данных. Я обновил версию базы данных и добавил еще несколько новых столбцов. теперь, зомбируйте пользовательскую резервную копию старой базы данных версии 1. , и после того, как он попытается импортировать, он получит что-то вроде «(1) нет такого столбца: (И имя столбца здесь)». Как я могу вызвать onUpgrade в старой базе данных после импорта? Могу ли я вызвать onUpgrade на загруженные базы данных вручную? Как я могу решить эту проблему? Нужно ли сообщать пользователям после того, как они обновили приложение, чтобы снова выполнить резервное копирование для безопасного использования? Любая идея?Как импортировать старую версию файла базы данных в новую версию?

код, как я сделать импорт:

// importing database 
public boolean importDB(String path , File dbFile) { 
    try { 
     boolean isValid = checkDbIsValid(dbFile); 
      if(!isValid){ 
       Toast.makeText(context, context.getResources().getString(R.string.errorFile),Toast.LENGTH_LONG).show(); 
       return false; 
      } 

     //Last loaded file name will be the auto backup file destination 
     int lastIndexOf = path.lastIndexOf('/'); 
     String loadedFileName = path.substring(lastIndexOf + 1); 
     new MySharedPreferences(context).putStringLastFileNameSent(loadedFileName); 


     FileInputStream fis = new FileInputStream(path); 
     //Destination to: 
     String outFileName = DATABASE_DIRECTORY + DbContract.DB_NAME; 

     OutputStream output = new FileOutputStream(outFileName); 
     byte[] buffer = new byte[1024]; 
     int length; 
     while ((length = fis.read(buffer)) > 0) { 
      output.write(buffer, 0, length); 
     } 
     // Close the streams 
     output.flush(); 
     output.close(); 
     fis.close(); 

     Toast.makeText(context, context.getResources().getString(R.string.importDatabaseSucceed),Toast.LENGTH_LONG).show(); 

     return true; 
    } catch (Exception e) { 
     Toast.makeText(context,context.getResources().getString(R.string.errorImportDatabase),Toast.LENGTH_LONG).show(); 
     e.printStackTrace(); 
     return false; 
    } 
} 

И это Как я могу проверить, если файл datbase действует:

public static boolean checkDbIsValid(File db) { 
     SQLiteDatabase sqlDb; 
     Cursor cursor; 
     try { 
      sqlDb = SQLiteDatabase.openDatabase (db.getPath(), null, SQLiteDatabase.CONFLICT_NONE); 
      cursor = sqlDb.query(true,DbContract.TABLE_DAY, null, null, null, null, null, null, null); 
      for(String s : DbContract.ALL_COLUMN_KEYS_IN_TABLE_DAY){ 
         cursor.getColumnIndexOrThrow(s); 
      } 

      //This make sure the user can import old database on new Version of table 
      try { 
       cursor = sqlDb.query(true,DbContract.TABLE_SETTING,null, null, null, null, null, null, null); 
       for(String s : DbContract.ALL_COLUMN_KEYS_IN_TABLE_SETTING_v2){ 
        cursor.getColumnIndexOrThrow(s); 
       } 
       System.out.println("DATABASE LOADED FROM V2"); 
      }catch (Exception fileNotV1){ 
       System.out.println("ERROR FILE .. IS NOT V2"); 
       try { 
        for(String s : DbContract.ALL_COLUMN_KEYS_IN_TABLE_SETTING_v1){ 
         cursor.getColumnIndexOrThrow(s); 
        } 

        System.out.println("DATABASE LOADED FROM V1"); 
       }catch (Exception fileNotV2){ 
        System.out.println("ERROR FILE .. IS NOT V1"); 
        return false; 
       } 
      } 

      if(DbContract.VERSION<sqlDb.getVersion()){ 
       return false; 
      } 
      sqlDb.close(); 
      cursor.close(); 
     } catch (IllegalArgumentException e) { 
      e.printStackTrace(); 
      return false; 
     } catch (SQLiteException e) { 
      e.printStackTrace(); 
      return false; 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return false; 
     } 
     return true; 
    } 

общественного класса DbHelper расширяет SQLiteOpenHelper {

public DbHelper(Context context) { 
     super(context, DbContract.DB_NAME, null, DbContract.VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.execSQL(DbContract.CREATE_TABLE_WORKS); 
     db.execSQL(DbContract.CREATE_TABLE_SETTING); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     if (oldVersion == 1) { 
      updateToVersion2(db); 
     } 
    } 

    public void updateToVersion2(SQLiteDatabase db){ 
     db.execSQL("ALTER TABLE " + DbContract.TABLE_SETTING + " ADD " 
       + DbContract.COLUMN1 + " REAL DEFAULT 1"); 
     db.execSQL("ALTER TABLE " + DbContract.TABLE_SETTING + " ADD " 
       + DbContract.COLUMN0 + " REAL DEFAULT 0"); 
     db.execSQL("ALTER TABLE " + DbContract.TABLE_SETTING + " ADD " 
       + DbContract.COLUMN2 + " REAL DEFAULT 0"); 
    } 
    } 
+0

Можете ли вы описать, как вы экспортируете и импортируете данные? Вы буквально копируете файл базы данных в другое место хранения и из него? Или вы делаете что-то еще? – Karakuri

+0

Я беру файл db из данных/данных приложения ... и копирую его в локальное хранилище. и для импорта я просто переопределяю существующий файл – Anna

ответ

1

Если вы буквально копируете файл db в хранилище и из него, тогда теоретически, когда вы вызываете getReadableDatabase() или getWriteableDatabase(), он должен проверить версию базы данных и пройти типичный поток обновления, который вызывает onUpgrade() и дает вам как старые, так и новые номера версий. Если это так, и если вы правильно применяете onUpgrade(), тогда все должно «просто работать».

Если обновление не происходит автоматически, после открытия базы данных вы можете сами проверить версию базы данных с помощью getVersion() и выполнить любые команды, которые вы хотите обновить схему вручную.

EDIT

В для onUpgrade() для автоматического запуска, необходимо открыть базу данных с помощью DbHelper класса. При отсутствии этого вам понадобится экземпляр DbHelper, чтобы вы могли вызвать его метод onUpgrade() и передать его SQLiteDatabase, который вы открыли вручную.

SQLiteDatabase sqlDb = ...; 
DbHelper dbHelper = ...; 
dbHelper.onUpgrade(sqlDb, sqlDb.getVersion(), DbContract.VERSION); 

Я не особо люблю ваш метод, чтобы проверить, действительно ли файл DB. Вам нужно будет отслеживать каждую версию схемы в вашем контракте и проверять каждый; что кажется громоздким. Что, если вместо этого вы скопируете файл в файл temp в каталоге своей базы данных приложения, откройте его с помощью DbHelper (который должен попытаться открыть его), и если что-то не удается, вы можете прервать и удалить файл? Если это удастся, вы можете просто переименовать файл и снова открыть базу данных. Вероятно, я подошел к нему.

+0

Пожалуйста, смотрите выше. Я обновляю свой вопрос. Можете ли вы мне помочь и показать мне, где и как мне нужно позвонить onUpgrade? – Anna

+0

@ Anna see my edit – Karakuri

+0

Хорошо спасибо. Можете ли вы показать мне примерный код? – Anna

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