How to properly use SQLCipher 4.5.0 on Android?

Hi. We were using SQLCipher 3.x and 4.x in our Android application. When migrating from version 3.x to version 4.x we were struggling a bit on how to properly migrate the database. We ended up with a code snippet:

  override fun migrateDatabase(file: File, password: String): SQLiteDatabase {
    return SQLiteDatabase.openOrCreateDatabase(file, password, null, MigrationHook())
  }

  // see https://discuss.zetetic.net/t/upgrading-to-sqlcipher-4/3283
  private class MigrationHook : SQLiteDatabaseHook {
    override fun preKey(database: SQLiteDatabase?) { /* not used */
    }

    override fun postKey(database: SQLiteDatabase?) {
      database?.rawExecSQL("PRAGMA cipher_migrate")
    }
  }

The code snippet was working fine. But now as we can read in 4.5.0 release notes the cipher_migrate PRAGMA could fail and in such case the app would still work with the non-migrated version of the DB. With version 4.5.0 it is advised to actually check if the migration fails to prevent further read/write issues.

My question is what is the recommended way to verify if migration works fine? Should we still use the SQLiteDatabaseHook for the migration? The rawExecSQL is not supposed to return any values so which method should we use instead? Is the public Cursor rawQuery(String sql, String[] selectionArgs, int initialRead, int maxRead) a way to go? Should we throw some RuntimeException in postKey body to propagate the issue?

Best regards,
Robert

Are there no official recommendations on how to implement the migration?

Hi @robertszuba

My apologizes for the delayed response. When you execute PRAGMA cipher_migrate, you will want to check the return value (i.e., 0 is success). Here is an example within our Android test suite. In terms of how you should communicate a migration error state, that would be very application specific. We’ve shared general guidance for upgrading to the major version 4 of SQLCipher here.