Are there any existing alternatives for SQLDatabaseHook for Android Room

From what I have understood of the README and Docs, I should use SQLDatabaseHook interface to execute my SQL statements in prekey() method then maybe clean up on postKey(). However, the only parameter for this interface’s method is a SQLiteDatabase object, which I am able to query on the prekey() hook using sql query(), so I guess it’s the sqlite equivalent of the room database object I build. I would however like to continue using my RoomDatabase objects as before rather than having to use queries but cannot find an equivalent hook I can extend to use a prepared Roomdatabase rather than SQLiteDatabase object as an argument, so that I can in turn use the DAO. Is this doable in SQLCipher?, all the implementations I’ve seen access the unencrypted DB as a SQLDatabase.

Hi @marzipan,

The SQLiteDatabaseHook predates the Room/Support API. The purpose is to provide a seam for interfacing with the database connection immediately before and after the keying operation is performed. At the point of invocation, SQLCipher is not aware of a RoomDatabase instance per se, just the underlying connection which is exposed to the callbacks with a SQLiteDatabase instance.

I had misunderstood it then, infact my warped understanding made me wonder if id have to dump the singleton pattern and build everytime i wanted to use database. What I needed to know then is how I would access the encrypted database consequently. Say I have encrypted it with this code `public abstract class OfflineDatabase extends RoomDatabase {
public abstract RegistrationInfoDAO registrationInfoDAO();
public static final String DB_NAME=“SOME_DB”;
private static volatile OfflineDatabase DB_INSTANCE=null;

public static synchronized OfflineDatabase getInstance(Context context){
    if (DB_INSTANCE!=null){
        return DB_INSTANCE;
    }
    else{

        String passwd="123";


        final byte[] passphrase = SQLiteDatabase.getBytes(passwd.toCharArray());
        final SupportFactory factory = new SupportFactory(passphrase);
        final OfflineDatabase offlineDatabase = Room.databaseBuilder(context, OfflineDatabase.class, DB_NAME)
                .openHelperFactory(factory)
                .build();
        return offlineDatabase;
}

}}`

My current attempt to access it using getInstance fails for any DAO operations OfflineDatabase offlineDatabase=OfflineDatabase.getInstance(appContext); with a sqlcipher.*.SQLException since database is already encrypted. The only alternatives I see online are using a SQLiteDatabaseObject openOrCreateDatabase() which can accept a password but that would not allow room operations. Any way to access my singleton instance while supplying a password? Thanks.

Hi @marzipan

You certainly don’t want to recreate a database instance every time, that is cost prohibitive with SQLCipher due to the time required for key derivation. From your getInstance(...) function, it appears that you will want to assign offlineDatabase to DB_INSTANCE in your else branch. That should allow you to create a single instance of the Room database reference.

Hi @developernotes. Yes I will use the singleton pattern for subsequent requests. My issue is with how i can supply a passkey to unlock the database while obtaining an instance of it, attempts to obtain my room singleton instance will throw the SQLiteError as its (rightfully) encrypted.

Hi @marzipan

My issue is with how i can supply a passkey to unlock the database while obtaining an instance of it

You could provide that somewhere within the class that is exposing the singleton instance of the database.