【问题标题】:Does SQLite.swift has the ability to detect & notify table data change?SQLite.swift 是否有能力检测和通知表数据变化?
【发布时间】:2021-01-05 03:33:08
【问题描述】:

我想知道,SQLite.swift 是否有能力检测并通知表数据更改? (类似于NSFetchedResultsController 提供的,用于检测和通知实体数据更改)


对于GRDB.swift,它提供了观察表数据变化的能力。

https://github.com/groue/GRDB.swift/blob/master/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/ViewControllers/PlayerListViewController.swift#L98

private func configureDataSourceContent() {
    switch playerOrdering {
    case .byName:
        playersCancellable = AppDatabase.shared.observePlayersOrderedByName(
            onError: { error in fatalError("Unexpected error: \(error)") },
            onChange: { [weak self] players in
                guard let self = self else { return }
                self.updateDataSourceContent(with: players)
            })
    case .byScore:
        playersCancellable = AppDatabase.shared.observePlayersOrderedByScore(
            onError: { error in fatalError("Unexpected error: \(error)") },
            onChange: { [weak self] players in
                guard let self = self else { return }
                self.updateDataSourceContent(with: players)
            })
    }
}

SQLite 本身确实提供低级数据更改通知回调 (https://www.sqlite.org/c3ref/update_hook.html)。

SQLite.swift 是否通过在sqlite3_update_hook 的顶部构建提供开箱即用的功能?如果没有,我们是否可以自定义构建这样的解决方案?

谢谢。

【问题讨论】:

  • GRDB 付出了很多的努力,使 SQLite 观察对应用程序尽可能简单。您可以查看 GRDB 源代码并使用 various hooks exposed by SQLite.swift 来重现相同的行为。我认为你不会找到现成的答案。
  • 简而言之,GRDB 使用 1. SQLite 更新、提交和回滚钩子来跟踪已提交的更改, 2. SQLite 授权器以跟踪保存点,因此不会通知回滚的更改, 3. SQLite 授权器,以便了解跟踪请求中涉及哪些表和列, 4. SQLite 授权器,以便发现哪些语句有机会影响跟踪的请求, 5. SQLite WAL 模式,以便有效地获取更新的值在跟踪的请求受到事务影响后,6. SQLite.swift 完全缺乏的健壮并发模型。
  • 也许...毕竟你只是在照顾 GRDB ;-)

标签: ios swift sqlite sqlite.swift


【解决方案1】:

这对你有帮助吗?

SQift/hook.swift

发件人 - SQift

【讨论】:

    【解决方案2】:

    我相信,您正在寻找this 功能(转载如下以供参考):

    /// Registers a callback to be invoked whenever a row is inserted, updated,
        /// or deleted in a rowid table.
        ///
        /// - Parameter callback: A callback invoked with the `Operation` (one of
        ///   `.Insert`, `.Update`, or `.Delete`), database name, table name, and
        ///   rowid.
        public func updateHook(_ callback: ((_ operation: Operation, _ db: String, _ table: String, _ rowid: Int64) -> Void)?) {
            guard let callback = callback else {
                sqlite3_update_hook(handle, nil, nil)
                updateHook = nil
                return
            }
    
            let box: UpdateHook = {
                callback(
                    Operation(rawValue: $0),
                    String(cString: $1),
                    String(cString: $2),
                    $3
                )
            }
            sqlite3_update_hook(handle, { callback, operation, db, table, rowid in
                unsafeBitCast(callback, to: UpdateHook.self)(operation, db!, table!, rowid)
            }, unsafeBitCast(box, to: UnsafeMutableRawPointer.self))
            updateHook = box
        }
        fileprivate typealias UpdateHook = @convention(block) (Int32, UnsafePointer<Int8>, UnsafePointer<Int8>, Int64) -> Void
        fileprivate var updateHook: UpdateHook?
    

    但是,似乎有人尝试包含您要查找的内容。 看看这个SQLite.swift issue。这是从 2017 年开始的,可能已经进化了!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-11
      • 2020-12-21
      • 1970-01-01
      • 1970-01-01
      • 2023-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多