I have a database created with SQLCipher 3.5.1. I tried migrating it to SQLCipher 4.1.3 using PRAGMA cipher_migrate
according to the guidelines, but even though the database opens immediately after the openDatabase()
call, it does not actually migrate.
You can find the code I used below:
import android.content.Context;
import net.sqlcipher.Cursor;
import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteDatabaseHook;
public class DatabaseMigrator {
static public void checkAndMigrateDatabase(Context context, String databaseName, String password) {
String path = context.getDatabasePath(databaseName).getPath();
SQLiteDatabaseHook hook = new SQLiteDatabaseHook() {
@Override
public void postKey(SQLiteDatabase database) {
Cursor c = database.rawQuery("PRAGMA cipher_migrate", null);
Boolean migrationOccurred = false;
if (c.getCount() == 1) {
c.moveToFirst();
String selection = c.getString(0);
migrationOccurred = selection.equals("0");
print("selection: " + selection);
}
c.close();
print("migrationOccurred: " + migrationOccurred);
}
@Override
public void preKey(SQLiteDatabase database) { }
};
SQLiteDatabase database = null;
try {
database = SQLiteDatabase.openDatabase(path, password, null, 0, hook);
}
catch (Exception e) {
print("Exception while trying to open db: " + e);
}
if (database != null) {
database.close();
}
}
}
Also, although the guidelines state that the value of the PRAGMA cipher_migrate
SQL result should be 0
after the migration, in my case it’s always 1
.
Next time I try to open the DB (on the next app launch) without the PRAGMA cipher_migrate
command, I get the “not a database” exception and upon opening the db using the DB Browser for SQLite app, I still have to use the SQLiteCipher 3 defaults, which indicates that the migration never happened.
On top of that, I managed to successfully open the db using PRAGMA cipher_compatibility=3
, so it looks like there’s an issue during the migration process.
Does anyone have any hints on how PRAGMA cipher_migrate
can be performed successfully so it’s not needed every time the app launches?