提问人:Captain Jacky 提问时间:8/26/2023 更新时间:8/26/2023 访问量:114
如何将 SQLDelight 与 SqlCipher 一起使用 (Kotlin Multiplatform)
How to use SQLDelight together with SqlCipher (Kotlin Multiplatform)
问:
我正在尝试使用 SqlCipher 加密我的 SQLDelight 数据库。我在 GitHub 上找到了一个合适的例子,但是,它使用了过时的 cwac-saferoom,它将 Room 与 SQLCipher for Android 连接起来。过时的库提到使用适用于 Android 的 SQLCipher。因此,考虑到上面提到的 GitHub 中的 NoteDelight 存储库和 SQLCipher Android 文档,我尝试实现这种方法。但是,我似乎不明白如何使这项工作起作用。
- 我遵循了 SQLDelight 文档并在 src/main/sqldelight 下实现了我的 .sq 文件,并添加了必要的导入。
- 在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
}
- 现在在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
}
- 我实现了我的数据库持有者类
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()
}
}
- Util 方法
fun createQueryWrapper(driver: SqlDriver): MyDatabase {
return MyDatabase(
driver = driver,
photoAdapter = /* My adapter */)
)
}
我首先打开干净的应用程序并使用我提供的密码创建数据库。然后,在登录页面中,我提供密码,应用程序再次调用该方法。然后我进入主页,所有存储库都从数据库中获取所有记录。这就是每个存储库发生错误的地方:initializeDatabase
initializeDatabase
android.database.sqlite.SQLiteException: no such table: address: , while compiling: SELECT * FROM address
我所遵循的方法是否正确,可以与 SQLDelight 一起实现 SqlCipher 加密以获得最佳实践?我是否遗漏了正确实施的示例?以及如何解决我的错误?谢谢。
答: 暂无答案
评论