Android sqlcipher upgrade issues

In my project,i use dbflow database and sqlcipher to encrypt.
Dbflow init
···
public void initDBflow() {

    DatabaseConfig.Builder builder = new DatabaseConfig.Builder(AppDatabase.class);

        builder.openHelper((databaseDefinition, listener) -> new SQLCipherHelperImpl(databaseDefinition, listener));
    
    FlowConfig.Builder flowConfigBuilder = FlowConfig.builder(this)
            .addDatabaseConfig(builder.build());

   
    FlowManager.init(flowConfigBuilder.build()); 
}

···

Here is my test result for upgrade.

I have see SQLCipher for Android Migration (android-database-sqlcipher to sqlcipher-android)

I know sqlcipher has two library net.zetetic:android-database-sqlcipher and net.zetetic:sqlcipher-android .
My project use net.zetetic:android-database-sqlcipher 3.5.9 .Now i want to upgrade it

Here is my test:
net.zetetic:android-database-sqlcipher 3.5.9net.zetetic:android-database-sqlcipher 4.5.4 is ok

when use this code

new SQLiteDatabaseHook() {
            @Override
            public void preKey(SQLiteDatabase sqLiteDatabase) {

            }

            @Override
            public void postKey(SQLiteDatabase database) {
                database.rawExecSQL("PRAGMA cipher_migrate;");
            }
        }

But i want upgrade net.zetetic:android-database-sqlcipher 3.5.9 to net.zetetic:sqlcipher-android:4.5.6 ,so i use this code

new SQLiteDatabaseHook() {
            @Override
            public void preKey(SQLiteConnection connection) {
             
            }

            @Override
            public void postKey(SQLiteConnection connection) {
                long ret= connection.executeForLong("PRAGMA cipher_migrate;",null, null);
                LogUtil.i("database upgrade ret:"+ret);
            }
        }

it does not work.

Log

 SQLiteLog      com.my.demo      E  (26) statement aborts at 2: [PRAGMA user_version;] file is not a database
 SQLiteLog      com.my.demo      E  (26) statement aborts at 2: [PRAGMA user_version;] file is not a database
 SQLiteLog      com.my.demo      E  (26) statement aborts at 2: [PRAGMA user_version;] file is not a database
 SQLiteLog      com.my.demo      E  (26) statement aborts at 2: [PRAGMA user_version;] file is not a database
				com.my.demo      I  SQLCipherHelperImpl$1.postKey(L:27): database upgrade ret:1
 SQLiteLog      com.my.demo      E  (1) SQL logic error in "SELECT COUNT(*) FROM sqlite_schema;"
 SQLiteDatabase com.my.demo      E  Failed to open database '/data/user/0/com.my.demo/databases/test.db'.
                                                                              android.database.sqlite.SQLiteException: SQL logic error (code 1): , while compiling: SELECT COUNT(*) FROM sqlite_schema;
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnection.nativePrepareStatement(Native Method)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:973)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnection.executeForLong(SQLiteConnection.java:628)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:240)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:202)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:475)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:189)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:181)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteDatabase.openInner(SQLiteDatabase.java:1028)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteDatabase.open(SQLiteDatabase.java:1013)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteDatabase.openDatabase(SQLiteDatabase.java:840)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:359)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:278)
                                                                              	at com.my.demo.database.MySQLCipherOpenHelper.getDatabase(MySQLCipherOpenHelper.java:73)
                                                                              	at com.raizlabs.android.dbflow.config.DatabaseDefinition.getWritableDatabase(DatabaseDefinition.java:257)
                                                                              	at com.raizlabs.android.dbflow.sql.queriable.ModelLoader.load(ModelLoader.java:36)
                                                                              	at com.raizlabs.android.dbflow.sql.language.BaseModelQueriable.querySingle(BaseModelQueriable.java:69)
                                                                              	at com.raizlabs.android.dbflow.sql.language.BaseTransformable.querySingle(BaseTransformable.java:106)

what should i do for this upgrade?

then i test another one
net.zetetic:android-database-sqlcipher 4.5.4net.zetetic:sqlcipher-android:4.5.6 is also error ,for this test i dont use code connection.executeForLong("PRAGMA cipher_migrate;", null, null);
Log

SQLiteLog      com.my.demo      E  (26) file is not a database in "SELECT COUNT(*) FROM sqlite_schema;"
				com.my.demo      W  JNI critical lock held for 542.604ms on Thread[1,tid=25244,Runnable,Thread*=0x726563f800,peer=0x72808928,"main"]
SQLiteDatabase com.my.demo      E  Failed to open database '/data/user/0/com.my.demo/databases/test.db'.
                                                                              android.database.sqlite.SQLiteException: file is not a database (code 26): , while compiling: SELECT COUNT(*) FROM sqlite_schema;
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnection.nativePrepareStatement(Native Method)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:973)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnection.executeForLong(SQLiteConnection.java:628)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:240)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:202)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:475)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:189)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:181)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteDatabase.openInner(SQLiteDatabase.java:1028)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteDatabase.open(SQLiteDatabase.java:1013)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteDatabase.openDatabase(SQLiteDatabase.java:840)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:359)
                                                                              	at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:278)
                                                                              	at com.my.demo.database.MySQLCipherOpenHelper.getDatabase(MySQLCipherOpenHelper.java:73)
                                                                              	at com.raizlabs.android.dbflow.config.DatabaseDefinition.getWritableDatabase(DatabaseDefinition.java:257)
                                                                              	at com.raizlabs.android.dbflow.sql.queriable.ModelLoader.load(ModelLoader.java:36)
                                                                              	at com.raizlabs.android.dbflow.sql.language.BaseModelQueriable.querySingle(BaseModelQueriable.java:69)
                                                                              	at com.raizlabs.android.dbflow.sql.language.BaseTransformable.querySingle(BaseTransformable.java:106)

In my opinion, both of these are 4.x. why it can’t work? should i do some migrate?

Hi @xuhongchang,

The log output from your first run shows that other SQL statements are being run before the migration process provided by the SQLiteDatabaseHook. Because of this, key derivation has already occurred based on the SQLCipher 4 defaults and your migration is failing with a return value of 1. You will need to make adjustments to your application such that no other SQL commands are issued before keying and that cipher_migrate is invoked immediately after keying.

Which line of log?
Have you seen my several test results? Some can succeed while others don’t.The only difference between them is the database upgrade code.

net.zetetic:android-database-sqlcipher 3.5.9net.zetetic:android-database-sqlcipher 4.5.4 is ok

net.zetetic:android-database-sqlcipher 3.5.9 to net.zetetic:sqlcipher-android:4.5.6 not ok

net.zetetic:android-database-sqlcipher 4.5.4net.zetetic:sqlcipher-android:4.5.6 not ok

Is there a problem with my upgrade code?

gui application test result GUI TEST

Could it be caused by DBflow?

I have two failed upgrades and their failure logs look different ?
I need to solve these two upgrade problems, please tell me the solutions to each problem respectively

Can you give me a sample for upgrading and open database without dbflow, I’ll test it to rule out the influence of dbflow

This is the portion of the log I was referring to:

 SQLiteLog      com.my.demo      E  (26) statement aborts at 2: [PRAGMA user_version;] file is not a database
 SQLiteLog      com.my.demo      E  (26) statement aborts at 2: [PRAGMA user_version;] file is not a database
 SQLiteLog      com.my.demo      E  (26) statement aborts at 2: [PRAGMA user_version;] file is not a database
 SQLiteLog      com.my.demo      E  (26) statement aborts at 2: [PRAGMA user_version;] file is not a database
				com.my.demo      I  SQLCipherHelperImpl$1.postKey(L:27): database upgrade ret:1
 SQLiteLog      com.my.demo      E  (1) SQL logic error in "SELECT COUNT(*) FROM sqlite_schema;"

Unfortunately, we’re not familiar with DBFlow. Issuing a PRAGMA cipher_migrate in the postKey event of the SQLiteDatabaseHook is the suggested approach for upgrading the SQLCipher database file format on Android. You may want to evaluate your application code to determine if other SQL commands are being issued prior to the cipher_migrate call, alternatively, you might reach out to the authors of DBFlow to see if they have any suggestions.

I gui application test result GUI TEST

I also made mistakes when upgrading with the tool