Пользовательская миграция Sqlcipher для Android с 3 на 4

#android #database-migration #sqlcipher #sqlcipher-android

#Android #база данных-миграция #sqlcipher #sqlcipher-android

Вопрос:

Я обновил Sqlcipher для Android с 3.5.7 до 4.1.3 в своем приложении.

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

Я получаю это исключение при попытке открыть базу данных.

 net.sqlcipher.database.SQLiteException: file is not a database: , while compiling: select count(*) from sqlite_master;
    at net.sqlcipher.database.SQLiteCompiledSql.native_compile(Native Method)
  

Это мой код:

         SQLiteDatabaseHook mHook = new SQLiteDatabaseHook() {
            public void preKey(SQLiteDatabase database) {
                database.rawExecSQL("PRAGMA kdf_iter=1000;");
                database.rawExecSQL("PRAGMA cipher_default_kdf_iter=1000;");
                database.rawExecSQL("PRAGMA cipher_page_size = 4096;");
            }

            public void postKey(SQLiteDatabase database) {
                database.rawExecSQL("PRAGMA cipher_compatibility=3;");
            }
        };

        // this line generate the exception
        SQLiteDatabase database = SQLiteDatabase.openDatabase(oldDatabaseFile.getAbsolutePath(), password, null, SQLiteDatabase.OPEN_READWRITE, mHook);
        ...
        // migration code with ATTACH, sqlcipher_export etc... 
        ...
  

Файл существует, и пароль правильный: тот же фрагмент кода работает, если я понизил рейтинг библиотеки Sqlcipher. Что я делаю не так?

Ответ №1:

Я обнаружил ошибку:

Я создал базу данных с помощью sqlchipher 3, используя параметр cipher_page_size = 4096 , но он не принимается, поскольку использовалось значение по умолчанию.

Попытка выполнить миграцию, указав параметр, который, как я думал, использовался, не сработала. Мне просто нужно было удалить этот параметр и поместить все в postKey метод

 private final SQLiteDatabaseHook mHook = new SQLiteDatabaseHook() {
    public void preKey(SQLiteDatabase database) {
    }

    public void postKey(SQLiteDatabase database) {
        database.rawExecSQL("PRAGMA cipher_compatibility=3;");
        database.rawExecSQL("PRAGMA kdf_iter=1000;");
        database.rawExecSQL("PRAGMA cipher_default_kdf_iter=1000;");
    }
};
  

Комментарии:

1. Потребовалось много времени, чтобы найти ошибку. У меня возникли некоторые проблемы с открытием перенесенной базы данных в браузере sqlite db. Удалось ли вам открыть его после миграции?

2. Да, посмотрите на мой собственный ответ

3. @Gigi — нужно ли нам использовать этот mHook при каждом открытии базы данных или только в первый раз после обновления приложения?