Add observe(statement:) to TransactionObserver#1864
Conversation
|
Thank you @simolus3! I'll review this pull request in the next few days. At first glance, it does exactly what we talked about, and it does it well 👍 Please tell me if it allows PowerSync to achieve the goals you described in #1863, and in particular if later on you can call |
Yes, I've tested these changes with PowerSync and they seem to do exactly what we need :) My approach right now is to add a catchall observer in a |
|
I had a closer look, and I could spot a design flaw 🙂 Your changes closely reflect our initial intent, but I gave you a misleading direction. It won't be difficult to fix, fortunately! The symptom of the design flaw is that the new test fails if the observer returns false from private class EverythingObserver: TransactionObserver {
func observes(statement: Statement) -> Bool {
return true
}
func observes(eventsOfKind eventKind: GRDB.DatabaseEventKind) -> Bool {
- return true // test passes
+ return false // test fails
}
}This is definitely a bug. With this modification of the test, the The cause is that SQLite compiles the And there lies the design flaw: the truncate optimization is enabled or disabled from the compile-time authorization callbacks, before we can call The intention described at #1863 (comment) still holds:
It turns wrong in the next paragraph:
I think our only solution is to let observers opt in for all update events, without any filtering: protocol TransactionObserver {
- func observes(statement: Statement) -> Bool
+ var observesAllDatabaseChanges: Bool { get }
}If you lack time, I'll update this pull request accordingly. The |
That will definitely work for PowerSync too, I've changed the PR to be based on that 👍
I've added a small note on
I suppose "Changes performed by SQLite statements that are not both compiled and executed through GRDB APIs" implicitly covers that (since the function executes the statement with direct SQLite APIs internally, not with GRDB APIs). But it's good to be explicit about this, and I've expanded that bullet point.
I'm not really sure where we'd mention that, in the section about transaction observers controlling for which events they'd be invoked? I would be happy to expand the documentation with a bit more help from your side, but if you think it's quicker if you update this PR, then that's definitely fine with me as well :) |
|
Sounds great! OK I take charge of the remaining tidbits 👍 Thank you very much for your help 🙏 |
Some statements might issue writes to the databases through a layer of indirection (e.g. via a user-defined function). For these statements, GRDB is unable to detect the writes made and doesn't call
TransactionObserver.observes(eventKind:), doesn't install an update listener and has no way of observing these writes.This adds
TransactionObserver.observesAllDatabaseChanges, which can be used to make transaction observers listen for all database changes. It returnsfalseby default, but can be added to implementations to observe indirect statements as well.Closes #1863.
Pull Request Checklist
developmentbranch.make smokeTestterminal command runs without failure.