如何将 SQLDelight 与 SqlCipher 一起使用 (Kotlin Multiplatform)

How to use SQLDelight together with SqlCipher (Kotlin Multiplatform)

提问人:Captain Jacky 提问时间:8/26/2023 更新时间:8/26/2023 访问量:114

问:

我正在尝试使用 SqlCipher 加密我的 SQLDelight 数据库。我在 GitHub 上找到了一个合适的例子,但是,它使用了过时的 cwac-saferoom,它将 Room 与 SQLCipher for Android 连接起来。过时的库提到使用适用于 Android 的 SQLCipher。因此,考虑到上面提到的 GitHub 中的 NoteDelight 存储库和 SQLCipher Android 文档,我尝试实现这种方法。但是,我似乎不明白如何使这项工作起作用。

  1. 我遵循了 SQLDelight 文档并在 src/main/sqldelight 下实现了我的 .sq 文件,并添加了必要的导入。
  2. commonMain包下,我有
expect val databaseModule: Module

val repositoriesModule = module {
    single { AddressRepository(get()) }
    // more repositories
}
class AddressRepository(private val database: Database) {

    fun insertAddress(address: Address) =
        database.addressQueries.insertAddress(
            // parameters
        )

    // more functions
}
  1. 现在在androidMain中,我提供了databaseModule的实际实现:
actual val databaseModule: Module = module {
    single<Database> { AndroidDatabase(get()) }
}
abstract class DatabaseQueries {
    abstract val addressQueries: AddressQueries
    // more queries
}

abstract class Database : DatabaseQueries() {
    abstract fun initializeDatabase(passphrase: CharSequence = ""): DatabaseHolder

    // encrypt, decrypt, repass and other abstract methods
}

class AndroidDatabase(private val context: Context) : Database() {
    private var databaseHolder: DatabaseHolder? = null

    override val addressQueries: AddressQueries
        get() = initializeDatabase("").addressQueries

    override fun initializeDatabase(passphrase: CharSequence): DatabaseHolder {
        var instance = databaseHolder

        if (instance == null) {
            instance = AndroidDatabaseHolder(context, SpannableStringBuilder(passphrase))
            databaseHolder = instance
        }

        return instance
    }

    // other methods that override abstract methods
}
  1. 我实现了我的数据库持有者类
abstract class DatabaseHolder : DatabaseQueries() {
    abstract val database: MyDatabase
    abstract val driver: SqlDriver
}


class AndroidDatabaseHolder(
    context: Context,
    passphrase: CharSequence
) : DatabaseHolder() {

    init {
        System.loadLibrary("sqlcipher")
    }

    private val encryptedDatabase = SQLiteDatabase.openOrCreateDatabase(
        context.getDatabasePath(DATABASE_NAME),
        passphrase.toString(),
        null
    )

    override val driver = AndroidSqliteDriver(encryptedDatabase)
    override val database: MyDatabase = createQueryWrapper(driver)

    override val addressQueries: AddressQueries = database.addressQueries
    // more overriden queries

    override fun close() {
        driver.close()
    }

}
  1. Util 方法
fun createQueryWrapper(driver: SqlDriver): MyDatabase {
    return MyDatabase(
        driver = driver,
        photoAdapter = /* My adapter */)
    )
}

我首先打开干净的应用程序并使用我提供的密码创建数据库。然后,在登录页面中,我提供密码,应用程序再次调用该方法。然后我进入主页,所有存储库都从数据库中获取所有记录。这就是每个存储库发生错误的地方:initializeDatabaseinitializeDatabase

android.database.sqlite.SQLiteException: no such table: address: , while compiling: SELECT * FROM address

我所遵循的方法是否正确,可以与 SQLDelight 一起实现 SqlCipher 加密以获得最佳实践?我是否遗漏了正确实施的示例?以及如何解决我的错误?谢谢。

Android kotlin sqlcipher koin sqldelight

评论


答: 暂无答案