2013-04-17 4 views
0

Ниже вы можете увидеть мой вспомогательный класс базы данных. Я использую предварительно заполненную базу данных sqlite, импортированную в папку с ресурсами. Всякий раз, когда я добавляю таблицу в существующую базу данных, я не получаю такой ошибки таблицы, если мое приложение уже установлено на моем телефоне. Я думаю, мой метод onUpgrade() теперь настолько хорош. Это работает, не поймите меня неправильно, когда я меняю некоторые данные на существующие таблицы, я увеличиваю версию db и обновляюсь. Но если я добавлю таблицу, я получу ошибку.Как должен выглядеть мой метод onUpgrade()?

public class DataBaseHelper extends SQLiteOpenHelper 
{ 
private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window 
//destination path (location) of our database on device 
private static String DB_PATH = "/data/data/rs.androidaplikacije.themostcompleteiqtest/databases/"; 
private static String DB_NAME ="pitanja.sqlite";// Database name 
private static SQLiteDatabase mDataBase; 
private final Context mContext; 
private static final int DATABASE_VERSION = 3; 

public DataBaseHelper(Context mojContext) 
{ 
    super(mojContext, DB_NAME, null, 3);// 1 it's Database Version 
    DB_PATH = mojContext.getApplicationInfo().dataDir + "/databases/"; 
    this.mContext = mojContext; 
} 

public void createDataBase() throws IOException 
{ 
    //If database not exists copy it from the assets 


     this.getReadableDatabase(); 
     this.close(); 
     try 
     { 
      //Copy the database from assests 
      copyDataBase(); 
      Log.e(TAG, "createDatabase database created"); 
     } 
     catch (IOException mIOException) 
     { 
      throw new Error("ErrorCopyingDataBase"); 
     } 
    } 

/** 
* Check if the database already exist to avoid re-copying the file each time you open the application. 
* @return true if it exists, false if it doesn't 
*/ 
public boolean checkDataBase(){ 

SQLiteDatabase checkDB = null; 

try{ 
String myPath = DB_PATH + DB_NAME; 
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 

}catch(SQLiteException e){ 

//database does't exist yet. 

} 

if(checkDB != null){ 

checkDB.close(); 

} 

return checkDB != null ? true : false; 
} 
    /*Check that the database exists here: /data/data/your package/databases/Da Name 
    private boolean checkDataBase() 
    { 
     File dbFile = new File(DB_PATH + DB_NAME); 
     //Log.v("dbFile", dbFile + " "+ dbFile.exists()); 
     return dbFile.exists(); 
    } 
    */ 

    //Copy the database from assets 
    private void copyDataBase() throws IOException 
    { 
     InputStream mInput = mContext.getAssets().open(DB_NAME); 
     String outFileName = DB_PATH + DB_NAME; 
     OutputStream mOutput = new FileOutputStream(outFileName); 
     byte[] mBuffer = new byte[1024]; 
     int mLength; 
     while ((mLength = mInput.read(mBuffer))>0) 
     { 
      mOutput.write(mBuffer, 0, mLength); 
     } 
     mOutput.flush(); 
     mOutput.close(); 
     mInput.close(); 
    } 

    //Open the database, so we can query it 
    public boolean openDataBase() throws SQLException 
    { 
     String mPath = DB_PATH + DB_NAME; 
     //Log.v("mPath", mPath); 
     mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY); 
     //mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS); 
     return mDataBase != null; 
    } 
    @Override 
    public void close() 
    { 
     if(mDataBase != null) 
      mDataBase.close(); 
     super.close(); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase arg0) { 
     } 

    @Override 
    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) { 
     try { 
      // delete existing? 

      // Copy the db from assests 
      copyDataBase(); 
      Log.e(TAG, "database updated"); 
     } catch (IOException mIOException) { 
      Log.e(TAG, mIOException.toString()); 
      try { 
       throw mIOException; 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

} 

ответ

1

Существует 2 способа сделать onUpgrade, в зависимости от вашего приложения.

1) Бросьте все свои старые таблицы, а затем запустите onCreate. Это в основном уничтожает все ваши старые данные и начинается. Это хорошая техника, если вы можете каким-то образом восстановить старые данные или просто не заботитесь об этом.

2) Осторожно поддерживайте разницу в схеме между каждой выпущенной версией и записывайте операторы SQL для внесения правильных изменений между ними: добавьте новые таблицы, измените существующие таблицы для добавления/удаления столбцов и т. Д. Это требует много времени и хрупкие, поэтому используйте это только в том случае, если вам необходимо сохранить данные между этими версиями.

+0

Итак, как это сделать? Должен ли я удалить весь мой код из onUpgrade? Это хорошо? – marjanbaz

+0

Итак, вы копируете его из каталога ресурсов. Это в основном касается моего пути №1, но начиная с предопределенного db. Идея звуковая, я не вижу вопиющих дефектов в вашем коде. Какая у вас ошибка? И когда вы говорите добавить таблицу - вы добавляете ее в db в файле активов или просто в код? Потому что, если это просто код, вы можете попытаться прочитать/записать из этой таблицы, прежде чем создавать его, что, очевидно, является ошибкой. Лучше всего, чтобы каждый стол, созданный в db в вашем файле активов, если вы так делаете. –

+0

[Здесь вы можете увидеть эту ошибку] ​​(http://stackoverflow.com/questions/16067152/no-such-table-error-whenever-i-add-some-table-to-my-db). Я добавляю таблицу над дополнением SQLite Manager Firefox к базе данных в файле активов. – marjanbaz

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