Обновить БД.Библиотека Sqlite-asset-helper - PullRequest
0 голосов
/ 16 декабря 2018

Я использую библиотеку android-sqlite-asset-helper

Необходимо обновить, но чтобы пользователь сохранил данные.Названия таблиц, столбцов остались прежними.Увеличилось только количество записей в таблицах.

Я увеличил DATABASE_VERSION.Поместите базу данных в архив.Как указано в инструкции, создан файл - brodsky.db_upgrade_1-2.sql

ALTER TABLE "poems_table" RENAME TO 'poems_table_TMP'; CREATE TABLE
        "poems_table" ( "id" long NOT NULL, "title" text, "poem" text,
        "subject" text, "years" text, "favorite" text, PRIMARY KEY ("id") );
        INSERT INTO "poems_table"  ("id", "title", "poem", "subject",
        "years", "favorite") SELECT "id", "title", "poem", "subject",
        "years", "favorite" FROM "poems_table_TMP"; DROP TABLE
        "poems_table_TMP";

DbHelper

public class PoemsDbHelper extends SQLiteAssetHelper {

    private static String DB_NAME = "brodsky.db";
    private static final int DB_VERSION = 2;

    public PoemsDbHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }
}

ничего не изменилось.старые данные отображаются

1 Ответ

0 голосов
/ 18 декабря 2018

Исходя из вашего кода и предполагая, что код находится в методе onUpgrade и что версия была изменена с 1 на 2, код ничего не использует.Вот и все: -

  1. переименовывает таблицу poems_table старой базы данных
  2. создает новую таблицу poems_table
  3. копирует содержимое переименованной таблицы во вновь созданную таблицу
  4. удаляет переименованную таблицу poems_table.

Нигде не имеет доступа к более новой версии brodsky.db

Что вам нужно (я считаю), чтобы открыть, это более новая версияbrodsky.db и скопируйте данные из этой базы данных.

Рабочий пример

Ниже приведен код для такого рабочего примера.

Это будет при увеличении версии базы данных (для простоты любого обновления): -

  1. скопировать новую обновленную базу данных как отдельную / дополнительную базу данных и
  2. попытаться скопировать строки из обновленной базы данных в существующую базу данных
    1. , только если они не являются существующими строками (на основе всех столбцов, кроме столбца идентификатора, поскольку конечный пользователь мог добавить стихи и, следовательно, использовать идентификаторы).

код ядра находится в пределах PoemsDbHelper.java и составляет: -

public class PoemsDbHelper extends SQLiteAssetHelper {

    public static final String DBNAME = "brodsky.db";
    public static final int DBVERSION = 1;

    public static final String TBLNAME = "poems_table";

    public static final String COL_ID = "id";
    public static final String COL_TITLE = "title";
    public static final String COl_POEM = "poem";
    public static final String COL_SUBJECT = "subject";
    public static final String COL_YEARS = "years";
    public static final String COL_FAVOURITE = "favorite";

    Context mContext;

    public PoemsDbHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mContext = context;
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        getNewPoems(mContext, db); //<<<<<<<<<< get the new poems when upgraded
    }


    private void getNewPoems(Context context, SQLiteDatabase db) {

        Log.d("GETNEWPOEMS","Initiating getting new poems due to Database version increased.");

        // Prepare to copy the updated database from the assets folder
        InputStream is;
        OutputStream os;
        final String tempnewdbname = "tempbrodsky.db";
        int buffersize = 4096;
        byte[] buffer = new byte[buffersize];
        String newDBPath = mContext.getDatabasePath(tempnewdbname).getPath();

        // If a copied version of the updated database exists then delete it
        // This should not be required but better safe than sorry
        File newDBFile = new File(newDBPath);
        if (newDBFile.exists()) {
            newDBFile.delete();
        }

        // Just in case create the databases directory (it should exist)
        File newDBFileDirectory = newDBFile.getParentFile();
        if (!newDBFileDirectory.exists()) {
            newDBFileDirectory.mkdirs();
        }

        // Preapre to copy update database from the assets folder
        try {
            is = context.getAssets().open("databases/" + DBNAME);
            os = new FileOutputStream(newDBFile);
            int bytes_read;
            while ((bytes_read = is.read(buffer,0,buffersize)) > 0) {
                os.write(buffer);
            }
            os.flush();
            os.close();
            is.close();

        }catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("Ouch updated database not copied - processing stopped - see stack-trace above.");
        }

        long id = maxid(db) + 1; // Get the next available id
        SQLiteDatabase newdb = SQLiteDatabase.openDatabase(newDBFile.getPath(),null,SQLiteDatabase.OPEN_READONLY);
        Cursor csr = newdb.query(TBLNAME,null,null,null,null,null,null);
        long insert_result;
        db.beginTransaction();
        while (csr.moveToNext()) {
            insert_result = insertCorePoem(
                    db,
                    id,
                    csr.getString(csr.getColumnIndex(COL_TITLE)),
                    csr.getString(csr.getColumnIndex(COl_POEM)),
                    csr.getString(csr.getColumnIndex(COL_SUBJECT)),
                    csr.getString(csr.getColumnIndex(COL_YEARS)),
                    csr.getString(csr.getColumnIndex(COL_FAVOURITE))
            );
            // If the row was inserted then increment the if ready for the next insert
            // If not inserted (result = -2) then leave id as it is as it was unused
            if (insert_result > 0) {
                id++;
            }

        }
        db.setTransactionSuccessful();
        db.endTransaction();
        csr.close();
        newDBFile.delete(); // Delete the copied database as no longer required
    }

    public long insertCorePoem(SQLiteDatabase db, long id, String title, String poem, String subject, String years, String favourite) {

        String whereclause = COL_TITLE + "=? AND " + COl_POEM + "=? AND " + COL_SUBJECT + "=? AND " + COL_YEARS + "=?";
        String[] whereargs = new String[]{
                title,
                poem,
                subject,
                years
        };

        Cursor csr = db.query(TBLNAME,null,whereclause,whereargs,null,null,null);
        boolean rowexists = (csr.getCount() > 0);
        csr.close();
        if (rowexists) {
            Log.d("INSERTCOREPOEM","Skipping insert of row");
            return -2; // Don't insert if the poem already exists
        }

        ContentValues cv = new ContentValues();
        cv.put(COL_ID,id);
        cv.put(COL_TITLE,title);
        cv.put(COl_POEM,poem);
        cv.put(COL_SUBJECT,subject);
        cv.put(COL_YEARS,years);
        cv.put(COL_FAVOURITE,favourite);
        Log.d("INSERTCOREPOEM","Inserting new column with id " + String.valueOf(id));
        return db.insert(TBLNAME, null, cv);
    }

    private long maxid(SQLiteDatabase db) {
        long rv = 0;
        String extractcolumn = "maxid";
        String[] col = new String[]{"max(" + COL_ID + ") AS " + extractcolumn};
        Cursor csr = db.query(TBLNAME,col,null,null,null,null,null);
        if (csr.moveToFirst()) {
            rv = csr.getLong(csr.getColumnIndex(extractcolumn));
        }
        csr.close();
        return rv;
    }

    public Cursor getAllPoems() {
        SQLiteDatabase db = this.getWritableDatabase();
        return db.query(TBLNAME,null,null,null,null,null,null);
    }
}
  • getNewPoems - это основной метод, который выполняет вышеперечисленное (обратите внимание, как он вызывается из метода onUpgrade).Это копирует обновленную базу данных из папки активов, а затем извлекает все стихи (основные стихи, поставляемые с приложением ()).
  • Подготовка к вставке столбцов получает текущий максимальный идентификатор из существующей базы данных, используя maxid и добавляет 1, чтобы новый первый идентификатор был уникальным.
  • Пытается вставить каждую строку НО, если строка для вставки уже существует, то она будет пропущена.Это определяется в методе insertCorePoem .
  • метод getAllPoems возвращает курсор (используемый активацией вызова).
  • Примечание у вас могут быть другие существующие методы, которые должны быть включены.

Тестирование

База данных с именем brodsky.db была создана с использованием внешнего инструмента с 3 стихами.Это было скопировано в папку базы данных в папке ресурсов.

Следующее использовалось в вызывающей деятельности: -

public class MainActivity extends AppCompatActivity {
    PoemsDbHelper mDBHlpr;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDBHlpr = new PoemsDbHelper(this);
        Log.d("DBVERSION", "Database version = " + String.valueOf(PoemsDbHelper.DBVERSION));
        Cursor csr = mDBHlpr.getAllPoems();
        DatabaseUtils.dumpCursor(csr);
        csr.close();
    }
}

Этап 1 - проверка / проверка существующей базы данных

При первом запуске база данных (с 3 стихами) копируется из папки ресурсов, и журнал содержит (как это происходит при каждом запуске приложения на этом этапе): -

12-18 06:19:58.505 3574-3574/? D/DBVERSION: Database version = 1
12-18 06:19:58.505 3574-3574/? W/SQLiteAssetHelper: copying database from assets...
12-18 06:19:58.505 3574-3574/? W/SQLiteAssetHelper: database copy complete
12-18 06:19:58.521 3574-3574/? I/SQLiteAssetHelper: successfully opened database brodsky.db
12-18 06:19:58.521 3574-3574/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@534758c8
12-18 06:19:58.521 3574-3574/? I/System.out: 0 {
12-18 06:19:58.521 3574-3574/? I/System.out:    id=1
12-18 06:19:58.521 3574-3574/? I/System.out:    title=A Poem
12-18 06:19:58.521 3574-3574/? I/System.out:    poem=This is a poem
12-18 06:19:58.521 3574-3574/? I/System.out:    subject=poem
12-18 06:19:58.521 3574-3574/? I/System.out:    years=2018
12-18 06:19:58.521 3574-3574/? I/System.out:    favorite=NO
12-18 06:19:58.521 3574-3574/? I/System.out: }
12-18 06:19:58.521 3574-3574/? I/System.out: 1 {
12-18 06:19:58.521 3574-3574/? I/System.out:    id=2
12-18 06:19:58.521 3574-3574/? I/System.out:    title=Another Poem
12-18 06:19:58.521 3574-3574/? I/System.out:    poem=This is another poem
12-18 06:19:58.521 3574-3574/? I/System.out:    subject=another poem
12-18 06:19:58.521 3574-3574/? I/System.out:    years=2017
12-18 06:19:58.521 3574-3574/? I/System.out:    favorite=NO
12-18 06:19:58.521 3574-3574/? I/System.out: }
12-18 06:19:58.521 3574-3574/? I/System.out: 2 {
12-18 06:19:58.521 3574-3574/? I/System.out:    id=3
12-18 06:19:58.521 3574-3574/? I/System.out:    title=the Third Poem
12-18 06:19:58.521 3574-3574/? I/System.out:    poem=This is the third poem
12-18 06:19:58.521 3574-3574/? I/System.out:    subject=third poem
12-18 06:19:58.521 3574-3574/? I/System.out:    years=2018
12-18 06:19:58.521 3574-3574/? I/System.out:    favorite=NO
12-18 06:19:58.521 3574-3574/? I/System.out: }
12-18 06:19:58.521 3574-3574/? I/System.out: <<<<<

Этап 2 - Использованиеобновленная база данных (но номер версии не изменился).

  1. 3 дополнительных строки были добавлены в базу данных с помощью инструмента SQlite
  2. Существующая база данных в папке ресурсов была переименована (легковернуться для тестирования отладки).
  3. Обновленная база данных была скопирована в папку баз данных в папке активов.

, что привело к: -

enter image description here

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

Этап 3 - Изменение номера версии.

Номер версии был увеличен с 12 и приложение запустится.

, в результате чего будут добавлены 3 строки в соответствии с: -

12-18 06:24:46.973 3689-3689/? D/DBVERSION: Database version = 2
12-18 06:24:46.981 3689-3689/? I/SQLiteAssetHelper: successfully opened database brodsky.db
12-18 06:24:46.981 3689-3689/? D/GETNEWPOEMS: Initiating getting new poems due to Database version increased.
12-18 06:24:46.981 3689-3689/? D/INSERTCOREPOEM: Skipping insert of row
12-18 06:24:46.985 3689-3689/? D/INSERTCOREPOEM: Skipping insert of row
12-18 06:24:46.985 3689-3689/? D/INSERTCOREPOEM: Skipping insert of row
12-18 06:24:46.985 3689-3689/? D/INSERTCOREPOEM: Inserting new column with id 4
12-18 06:24:46.985 3689-3689/? D/INSERTCOREPOEM: Inserting new column with id 5
12-18 06:24:46.985 3689-3689/? D/INSERTCOREPOEM: Inserting new column with id 6
12-18 06:24:46.993 3689-3689/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@53462060
12-18 06:24:46.993 3689-3689/? I/System.out: 0 {
12-18 06:24:46.993 3689-3689/? I/System.out:    id=1
12-18 06:24:46.993 3689-3689/? I/System.out:    title=A Poem
12-18 06:24:46.993 3689-3689/? I/System.out:    poem=This is a poem
12-18 06:24:46.993 3689-3689/? I/System.out:    subject=poem
12-18 06:24:46.993 3689-3689/? I/System.out:    years=2018
12-18 06:24:46.993 3689-3689/? I/System.out:    favorite=NO
12-18 06:24:46.993 3689-3689/? I/System.out: }
12-18 06:24:46.993 3689-3689/? I/System.out: 1 {
12-18 06:24:46.993 3689-3689/? I/System.out:    id=2
12-18 06:24:46.993 3689-3689/? I/System.out:    title=Another Poem
12-18 06:24:46.993 3689-3689/? I/System.out:    poem=This is another poem
12-18 06:24:46.993 3689-3689/? I/System.out:    subject=another poem
12-18 06:24:46.993 3689-3689/? I/System.out:    years=2017
12-18 06:24:46.993 3689-3689/? I/System.out:    favorite=NO
12-18 06:24:46.993 3689-3689/? I/System.out: }
12-18 06:24:46.993 3689-3689/? I/System.out: 2 {
12-18 06:24:46.993 3689-3689/? I/System.out:    id=3
12-18 06:24:46.993 3689-3689/? I/System.out:    title=the Third Poem
12-18 06:24:46.993 3689-3689/? I/System.out:    poem=This is the third poem
12-18 06:24:46.993 3689-3689/? I/System.out:    subject=third poem
12-18 06:24:46.993 3689-3689/? I/System.out:    years=2018
12-18 06:24:46.993 3689-3689/? I/System.out:    favorite=NO
12-18 06:24:46.993 3689-3689/? I/System.out: }
12-18 06:24:46.993 3689-3689/? I/System.out: 3 {
12-18 06:24:46.993 3689-3689/? I/System.out:    id=4
12-18 06:24:46.993 3689-3689/? I/System.out:    title=The Update Poem
12-18 06:24:46.993 3689-3689/? I/System.out:    poem=This is a new poem
12-18 06:24:46.993 3689-3689/? I/System.out:    subject=4th Core Poem
12-18 06:24:46.993 3689-3689/? I/System.out:    years=2019
12-18 06:24:46.993 3689-3689/? I/System.out:    favorite=NO
12-18 06:24:46.993 3689-3689/? I/System.out: }
12-18 06:24:46.993 3689-3689/? I/System.out: 4 {
12-18 06:24:46.993 3689-3689/? I/System.out:    id=5
12-18 06:24:46.993 3689-3689/? I/System.out:    title=Another Updated Poem
12-18 06:24:46.993 3689-3689/? I/System.out:    poem=This is another updated poem
12-18 06:24:46.997 3689-3689/? I/System.out:    subject=5th Core Poem
12-18 06:24:46.997 3689-3689/? I/System.out:    years=2019
12-18 06:24:46.997 3689-3689/? I/System.out:    favorite=NO
12-18 06:24:46.997 3689-3689/? I/System.out: }
12-18 06:24:46.997 3689-3689/? I/System.out: 5 {
12-18 06:24:46.997 3689-3689/? I/System.out:    id=6
12-18 06:24:46.997 3689-3689/? I/System.out:    title=The 3rd Updated Poem
12-18 06:24:46.997 3689-3689/? I/System.out:    poem=This is the 3rd updated poem
12-18 06:24:46.997 3689-3689/? I/System.out:    subject=6th Core Poem
12-18 06:24:46.997 3689-3689/? I/System.out:    years=2019
12-18 06:24:46.997 3689-3689/? I/System.out:    favorite=NO
12-18 06:24:46.997 3689-3689/? I/System.out: }
12-18 06:24:46.997 3689-3689/? I/System.out: <<<<<

Запустите приложение снова и ничего не изменится.

Увеличение версии до 3 приводит к тем же 6 строкам.Тем не менее, запускается onUpgrade, и делается попытка добавить строки, но все они пропущены, в соответствии с: -

12-18 06:27:08.933 3789-3789/so53801149.so53801149poemupdatefromassets D/DBVERSION: Database version = 3
12-18 06:27:08.937 3789-3789/so53801149.so53801149poemupdatefromassets I/SQLiteAssetHelper: successfully opened database brodsky.db
12-18 06:27:08.937 3789-3789/so53801149.so53801149poemupdatefromassets D/GETNEWPOEMS: Initiating getting new poems due to Database version increased.
12-18 06:27:08.937 3789-3789/so53801149.so53801149poemupdatefromassets D/INSERTCOREPOEM: Skipping insert of row
12-18 06:27:08.945 3789-3789/so53801149.so53801149poemupdatefromassets D/INSERTCOREPOEM: Skipping insert of row
12-18 06:27:08.945 3789-3789/so53801149.so53801149poemupdatefromassets D/INSERTCOREPOEM: Skipping insert of row
12-18 06:27:08.945 3789-3789/so53801149.so53801149poemupdatefromassets D/INSERTCOREPOEM: Skipping insert of row
12-18 06:27:08.945 3789-3789/so53801149.so53801149poemupdatefromassets D/INSERTCOREPOEM: Skipping insert of row
12-18 06:27:08.945 3789-3789/so53801149.so53801149poemupdatefromassets D/INSERTCOREPOEM: Skipping insert of row
12-18 06:27:08.949 3789-3789/so53801149.so53801149poemupdatefromassets I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@5347529c
..... results same as above (6 rows)
  • Примечание , вам может потребоваться настроить запрос в метод insertCorePoem для удовлетворения ваших потребностей.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...