onUpgrade база данных - oldVersion - новая версия - PullRequest
7 голосов
/ 24 августа 2011

Я использую этот DataBaseHelper.class и застрял в методе onUpgrade ().Я не знаю, как выяснить, какой номер версии базы данных.Я мог бы установить версию на 1, когда я впервые публикую ее, и когда я публикую обновление, я просто мог установить версию на 2 (myDataBase.setVersion(2);).Но это будет только 2, пока приложение работает.В следующий раз он будет запущен снова 1.То же самое происходит с private static int DATABASE_VERSION.Я думал о том, чтобы сохранить номер версии в дополнительной таблице, но, на мой взгляд, это не лучшая практика.

Итак, как вам убедиться, что номер версии увеличился после обновления и сохранилэто (значение, которое было присвоено private static int DATABASE_VERSION или myDataBase.getVersion();)?

DataBaseHelper-класс:

public class DataBaseHelper extends SQLiteOpenHelper {

    //The Android's default system path of your application database.
    private static String DB_PATH = "/data/data/com.mydatabase.db/databases/";

    private static String DB_NAME = "database.sl3";

    private SQLiteDatabase myDataBase;

    private final Context myContext;


    // Do you need this?
    private static int DATABASE_VERSION = 2;
    // or is this correct:
    // private static int DATABASE_VERSION = myDataBase.getVersion();


    /**
     * Constructor
     * Takes and keeps a reference of the passed context in order to access to
     * the application assets and resources.
     * 
     * @param context
     */
    public DataBaseHelper(Context context) {

        super(context, DB_NAME, null, DATABASE_VERSION);
        this.myContext = context;
    }

    /**
     * Creates an empty database on the system and rewrites it with your own
     * database.
     * */
    public void
        createDataBase() throws IOException {
        boolean dbExist = checkDataBase();

        if (dbExist) {


        }
        else {

            //By calling this method and empty database will be created into the default system path
            //of your application so we are gonna be able to overwrite that database with our database.


            this.getWritableDatabase();


            try {

               copyDataBase();

            } catch (IOException e) {

                throw new Error("Error copying database");

            }
        }

    }

    /**
     * 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
     */
    private boolean
        checkDataBase() {

        SQLiteDatabase checkDB = null;

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

        } catch (SQLiteException e) {

            //database does't exist yet.

        }

        if (checkDB != null) {

            checkDB.close();

        }
        return checkDB != null ? true : false;
    }

    /**
     * Copies your database from your local assets-folder to the just created
     * empty database in the
     * system folder, from where it can be accessed and handled.
     * This is done by transfering bytestream.
     * */
    private void
        copyDataBase() throws IOException {

        //Open your local db as the input stream
        InputStream myInput = myContext.getAssets().open(DB_NAME);


        // Path to the just created empty db
        String outFileName = DB_PATH + DB_NAME;


        //Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(outFileName);


        //transfer bytes from the inputfile to the outputfile
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }


        //Close the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();

    }

    public void 
       openDataBase() throws SQLException {

        //Open the database
        String myPath = DB_PATH + DB_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);



        // Which parameters do I have to pass?
        onUpgrade(myDataBase, DATABASE_VERSION, 2);
    }

    @Override
    public synchronized void
        close() {

        if (myDataBase != null)
            myDataBase.close();

        super.close(); 

    }

    @Override
    public void
        onCreate(SQLiteDatabase db) {

    }

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

    Log.d ("onUpgrade first log", Integer.toString(myDataBase.getVersion()));




    if (oldVersion == 1) {

        // do something


        // And then do this!?
        DATABASE_VERSION = 2;
        // or do this
        myDataBase.setVersion(2);
        Log.d ("onUpgrade sedond log", Integer.toString(myDataBase.getVersion()));

    }

    else {
        Log.d("onUpgrade", "else-clause: Already upgraded!");
    }



}

Ответы [ 2 ]

11 голосов
/ 24 августа 2011
// Do you need this?
private static int DATABASE_VERSION = 2;

Да, вам это нужно.(Еще лучше, сделайте это также final.)

Это сообщает помощнику базы данных, какая последняя версия схемы базы данных.Это должно быть исправлено в коде вашего приложения и увеличиваться всякий раз, когда вы изменяете схему.

Когда ваше приложение запускается, помощник во время выполнения проверяет, что представление вашего кода о последней версии совпадает с версией версиикоторый был активен, когда база данных была в последний раз создана или обновлена(Это то, для чего db.getVersion().) Если числа не совпадают, то помощник знает, что сохраненная база данных устарела по отношению к коду вашего приложения, и поэтому он запускает процедуру обновления.

Похоже, вы не создаете базу данных с нуля, а импортируете существующую базу данных из своих активов.Когда вы делаете этот первоначальный импорт, это время, когда нужно убедиться, что сохраненная версия соответствует версии вашего кода;либо примените его непосредственно к файлу базы данных в ваших ресурсах, либо, если вы уверены, что файл базы данных в ваших ресурсах соответствует коду, вы вызываете setVersion(DATABASE_VERSION).

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

1 голос
/ 03 апреля 2013

Добавление информации к ответу Грэма Борланда. Я объясню сценарий приложения, в котором ваша база данных находится в папке активов и вы копируете его в папку вашего пакета, если его там еще нет. Теперь, если вы хотите обновить свое приложение с обновленной базой данных. вам нужно установить

 private final static int DB_VERSION=2;          // Database Version

в вашем классе помощников по базам данных.

(Любое целое число, которое должно быть больше, чем начальная версия БД, которую вы установили изначально в этом классе)

После этого вам нужно добавить код для переопределения onUpgrade () В этом сценарии я перезаписываю старый БД на последний. Вы можете изменить свой код по своему вкусу

@Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
          CopyNewDatabaseFromAsset();
    } 

Если вам нужны какие-либо объяснения, пожалуйста, оставьте комментарий:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...