2012-03-11 5 views
0

У меня есть код ниже. Он правильно читает мой файл базы данных sqlite (который я уже создал с помощью SQLite Database Browser) в папке моих ресурсов - переносит его в каталог/data/data/packagename/databases/path на моем устройстве, тогда я могу использовать запрос и курсор для получения моей информации, и он отлично работает. Код здесь:Как обновить базу данных sqlite, предварительно заполненную на моем устройстве, без повторного создания таблиц?

public class DatabaseHelper extends SQLiteOpenHelper { 

private Context myDbContext; 
private static String dbName = "restaurant.db"; 
private static String outfilePath = "/data/data/dev.mypackage.com/databases/"; 
private static String path = outfilePath + dbName; 
private static SQLiteDatabase db; 

public DatabaseHelper(Context context){ 
    super(context, dbName, null, 2); 
    this.myDbContext = context; 
    db = openDb(); 
    String s = "select * from menu"; 
    Cursor c = db.rawQuery(s, null); 
    Log.e("DB Constructor Row count", String.valueOf(c.getCount()).toString()); 

    while(c.moveToNext()){ 
     Log.e("DB Constructor", c.getString(c.getColumnIndex("category"))); 
     Log.e("DB Constructor", c.getString(c.getColumnIndex("menuItem_id"))); 
     Log.e("DB Constructor", c.getString(c.getColumnIndex("title"))); 
     Log.e("DB Constructor", c.getString(c.getColumnIndex("desc"))); 
     Log.e("DB Constructor", c.getString(c.getColumnIndex("price"))); 
     Log.e("DB Constructor", c.getString(c.getColumnIndex("icon"))); 
    } 

    c.deactivate(); 
    c.close(); 
} 

private void copyDataBase(File dbFile) throws IOException { 
    try{ 
     InputStream dbStream = myDbContext.getAssets().open(dbName); 
     OutputStream newDbFile = new FileOutputStream(outfilePath + dbName); 

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

     newDbFile.flush(); 
     newDbFile.close(); 
     dbStream.close(); 
    } 
    catch(IOException e){ 

     throw new IOException("trying to copy the database - ERROR: " + e.getMessage()); 
    } 

} 

private SQLiteDatabase openDb() throws SQLiteException{ 
    File dbFile = myDbContext.getDatabasePath(dbName); 

    if(!dbFile.exists()){ 
     Log.e("openDb", "file does not exist"); 

     try { 
      copyDataBase(dbFile); 
     } catch (IOException e) { 
      throw new RuntimeException("Error creating source database", e); 
     } 
    } 

    return SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY); 

} 
public void loadRestaurantInfo(){ 

} 

@Override 
public void onCreate(SQLiteDatabase db){ 
    // TODO Auto-generated method stub  
} 

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

} 

Теперь я должен был вернуться и добавить строку информации в одной из таблиц (в базе данных в папке активов), используя SQLite Брауэр, - но это не отражается в мой вывод курсора - я понимаю, почему это происходит, потому что если (! dbFile.exists()) завершается сбой, значит, копирование не выполняется. Поэтому мой вопрос: какой код мне нужно добавить, чтобы сделать эту работу? Я никогда не создавал таблицы с кодом, поэтому я не вижу, насколько полезен метод onUpgrade для меня.

+1

Не прокладывайте пути. Используйте 'getDatabasePath()' для создания пути к файлу базы данных. – CommonsWare

ответ

1

У вас есть три варианта:

  1. Использование onUpgrade() (привилегированные)

  2. Удалите существующую базу данных и скопировать новый (не очень хорошая идея)

  3. Скопировать в данные в существующей базе данных, удалить существующую базу данных, скопировать новую базу данных, вставить данные из старой базы данных в новую базу данных (слишком много работы, когда новая схема базы данных может быть обновлена ​​в onUpgrade).

Итак, чтобы ответить на ваш вопрос, вы обновляете свою базу данных в onUpgrade() без необходимости воссоздавать любые таблицы.

С другой стороны, если вы только что добавили новую строку в определенную таблицу, схема базы данных не изменилась, и вы можете просто вставить новую строку во время выполнения ... конечно, не зная, что цель вашего приложения это не может быть хорошей идеей, так как вы можете легко потерять отслеживание изменений в вашей «статической» базе данных.

+1

OK, если я хочу сделать # 1 - onUpgrade, тогда я думаю, что мне интересно. так как я не собираюсь писать запросы (вставки, изменять таблицы и т. д.) в этом методе, как это делал большинство людей - тогда что именно я делаю? – cspam

+0

Вы можете сделать что-нибудь onUpgrade(). Идея состоит в том, чтобы управлять пользовательской версией базы данных. Я предлагаю вам использовать onUpgrade() для запуска простого SQL-запроса, который будет вставлять новую строку в соответствующую таблицу. Если вы дадите мне данные строки и имя таблицы, я могу показать вам пример, это очень просто. PS Мне нужны имена столбцов таблицы. – Luis

+0

Я понимаю, но то, что я пытался уйти, - это иметь кучу жестко запрограммированных запросов sql. Например, что, если мне нужно добавить 100 новых строк? Это заставило мою голову болеть. Что, если я должен был вернуться в следующий раз и удалить 25 из них, потому что я решил, что мне не нужны эти конкретные? то я должен выследить тех, кто просматривает все эти вставки. Я думал, что мне просто нужно будет создать новый файл базы данных или как-нибудь удалить базу данных, которая была создана (от копирования из активов) - не знаю, как это будет работать - – cspam

1

«Правильный» способ сделать что-то совсем не так, как вы изложили. Вместо того, чтобы идти туда, я предполагаю, что вы хотите сохранить свой текущий метод создания своей базы данных, и я предложу вам предложение по работе с ним. Добавьте таблицу в свою базу данных, в которой есть одна строка метаданных, которая будет включать в себя версию базы данных (а также все, что вам нравится). Если файл базы данных уже существует, откройте его и проверьте версию. Если версия устарела, закройте ее и замените.

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