在 swift 中,如何在信号应用程序分叉上访问数据库到 GRDB.swft/SQLCipher?

in swift how to access to database to GRDB.swft/SQLCipher on signal app fork?

提问人:biggreentree 提问时间:9/12/2023 最后编辑:biggreentree 更新时间:9/12/2023 访问量:65

问:

我目前正在开发信号消息传递应用程序的分支,这是我的应用程序的原始 5.22 版本。请看一下 repo。我不是这个分支的原始开发人员,也没有数据库经验。

更多信息:

我想执行本地加密和压缩备份,以便用户将其存储在 PC、磁盘或其他设备上。我通过复制数据库、WAL、附件等来做到这一点,将所有内容包含在一个文件中。此时用户已经安装了应用程序并启动了“恢复备份”路径,备份的所有文件都存储在一个新文件夹中。

应用程序正在使用 pod 来管理数据库。GRDB.swift/SQLCipher

旧数据库和新数据库以相同的方式装箱,我想它们使用相同的密码,在 init 中设置Configuration()

目标:我应该读取旧数据库并将数据写入刚刚创建的安装数据库,选择要覆盖(聊天)和保留的内容(设置、密钥等)。

因为我想我应该先在“导入”的数据库上打开数据库会话,所以我尝试这样做:

do {
var configuration = Configuration()
let dbQueueImported = try DatabaseQueue(path: importedSqlite.path) //here is crashing

//then I don't know what to do, some copy action maybe.

} catch {
print("error \(error)")
}

但 dbQueueImported 触发了此断言

extension Database {

//MARK: - database closing

///this method must be called before database deallocation

func close() {

SchedulingWatchdog.precodnitionValidQueue(self)
assert(!isClosed)

//rest of the code....

最后一件事,如果我注释断言,我会得到错误:

SQLite error 1 with statement 'SELECT * FROM sqlite_master LIMIT 1': unsupported file format.

我想我应该做点什么来打开/关闭连接

  • 我应该如何读/写或复制甚至访问数据库?
  • 有没有办法获取表和列的列表,以便选择要复制的信息?

即使你能告诉我是否有人发出信号,我可以寻求帮助也可能很有用

更新:

添加一个我得到的快速错误断点:

2023-09-12 14:28:52:702 Signal[8970:3357545] 🧡 [SDSDatabaseStorage.swift:355 write(file:function:line:block:)]: Database write on main thread.
2023-09-12 14:28:52:702 Signal[8970:3357545] 💛 [GRDBDatabaseStorageAdapter.swift:820 dbQueryLog(_:)]: BEGIN IMMEDIATE TRANSACTION
2023-09-12 14:28:52:704 Signal[8970:3357545] 💛 [GRDBDatabaseStorageAdapter.swift:820 dbQueryLog(_:)]:     INSERT INTO keyvalue (
        key,
        collection,
        value
    ) VALUES ('TSAccountManager_IsTransferInProgressKey', 'TSStorageUserAccountCollection', x'<139 byte>')
    ON CONFLICT (
        key,
        collection
    ) DO UPDATE
    SET value = x'<139 byte>'

在 Atomics.swift 中的本地化:

extension AtomicValue where T: Equatable {
    // Sets value to "toValue" IFF it currently has "fromValue",
    // otherwise throws.
    public func transition(from fromValue: T, to toValue: T) throws {
        try lock.perform {
            guard self.value == fromValue else {
                throw AtomicError.invalidTransition
            }
            self.value = toValue
        }
    }
}
swift 数据库 sqlite sqlcipher grdb

评论


答:

0赞 Gwendal Roué 9/12/2023 #1

在 GRDB 5.0.3 中移除了该断言:请考虑升级 GRDB 的副本。assert(!isClosed)

由于您可能没有运行 GRDB 5,请参阅迁移指南:

评论

0赞 biggreentree 9/12/2023
我不能,或者更准确地说,我不确定这对我来说是否可能。如您所见,我的项目基于旧版本的 signal 应用程序。我会检查你的链接,你能帮我阅读我导入的数据库并有选择地将信息复制到新数据库吗?我不明白该怎么做,以及我是否应该对密码做些什么
0赞 Gwendal Roué 9/12/2023
问题仅由首先无法打开的数据库触发:github.com/groue/GRDB.swift/issues/852。所以,如果你不能升级 GRDB,那么你就必须了解为什么实例创建失败。我建议你在 Xcode 中创建一个 Swift 错误断点,这样你就可以让调试器在断言启动程序之前暂停程序。很有可能,你会看到“文件不是数据库”数据库错误,因为你没有提供密钥来解密它。查看 github.com/groue/GRDB.swift/blob/master/README.md#encryptionassert(!isClosed)DatabaseQueue
0赞 biggreentree 9/12/2023
我尝试了更多,我得到了不同的消息,我更新了查询。考虑到数据库是由同一个应用程序生成的,我只是在重新安装应用程序后恢复数据库
0赞 Gwendal Roué 9/12/2023
设置错误断点是好的,但还不够:查看错误。如果你不看错误,你怎么能理解出了什么问题?只有当您知道出了什么问题时,您才能防止错误发生(在您的应用程序代码中)。不幸的是,您的应用程序无法打开连接,因为这个旧的 GRDB 版本会触发断言。但你必须明白,错误只是因为你的应用程序没有正确打开数据库而发生。因此,请观察错误,了解它,并修复您的应用程序,以便首先不会引发此错误。
0赞 biggreentree 9/13/2023
我的问题是关于正确打开数据库的,理论上,我正在这样做,我知道这个问题是关于打开或关闭与 dv 的连接,问题是,我不知道如何纠正。我没有压缩它 gRDB / SWLCipher。