SQLite Forum

sqlite3_update_hook - which changes are consiered?
Login

sqlite3_update_hook - which changes are consiered?

(1) By John 42 (jtheisen42) on 2022-10-14 02:32:48 [link] [source]

The documentation doesn't explicitly say which changes are considered for change listening. It could be

  1. Only changes on the connection the event is registered on.
  2. Only changes in the current process.
  3. All changes, including those made to the file by other processes.

I'm asking this because on

https://github.com/dotnet/efcore/issues/13827

the user Ciantic claims it's 1) and that would surprise me given the docs say nothing about it.

Can somebody say which it is?

(2) By Gunter Hick (gunter_hick) on 2022-10-14 11:13:45 in reply to 1 [link] [source]

Since the update_hook is registered on a connection - and is thus an attribute of said connection - it can only intercept changes invoked on said connection.

"The sqlite3_update_hook() interface registers a callback function with the database connection ..."

It cannot access any changes made outside of that connection; not even other threads in the same process using a different connection, much less changes by another process.

If you need cross process notification, you will either have to implement this yourself or poll pragma user_vrsion.

(3) By ddevienne on 2022-10-14 11:29:06 in reply to 2 [link] [source]

Perhaps you meant pragma data_version?

This post https://sqlite.org/forum/info/e76cac71ac2db298 has an interesting take on discovering changes
to a single (main) DB file, from any connection. (It's new to me, I need to remember it.)

(6) By Gunter Hick (gunter_hick) on 2022-10-15 06:55:10 in reply to 3 [link] [source]

Actually no.

There is schema_version, which counts to DDL changes to the file, so you (and SQLite itself) can determine if prepared statements needs to be re-prepared.

There is data_version, which is a computed property of a connection, that changes exactly when some other connection commits a change to the database file, ignoring changes by your connection.

There is sqlite3_update_hook() which provides notification of changes you yourself have performed (excluding some cases as documented).

There is user_version, which is managed completely by the user and can be used to indicate changes to the database that the application considers relevant.

(4.1) By John 42 (jtheisen42) on 2022-10-14 12:29:29 edited from 4.0 in reply to 2 [source]

Thanks for clearing that up.

I really think that should be documented, it's far from obvious.

The fact that the docs say that the callback is registered with a connection alone doesn't imply that changes only from that connections are considered: If there was a proper, global notification feature in sqlite, any listener would still be registered on a connection, wouldn't it? Where else if not on a connection? Connections are what manages all access to the database, after all.

I can only say I'm quite baffled that this isn't spelled out in the docs.

(5) By Gunter Hick (gunter_hick) on 2022-10-15 06:44:02 in reply to 4.1 [link] [source]

Please consider that SQLite is a library, not a client-server database. It runs completely within your process. A "connection" is a memory structure inside you process' address space. There is no record of a connection outside of your process.

Hence there is no such thing as a "listener" in SQLite, and no methods of IPC are provided.

(7.1) Originally by John 42 (jtheisen42) with edits by Stephan Beal (stephan) on 2022-10-17 18:02:24 from 7.0 in reply to 5 [link] [source]

Many standard programming libraries have data structures that can be subscribed for changes. .NET has ObservableCollection, for example.

These things are also in-process and have nothing to do with IPC.

It would be extremely helpful for UI development if there was a data store where you could subscribe to changes in the data you're displaying to the user.

Currently the docs read as if SQLite had such capabilities - and I'm pretty sure others read it like that as well given the activity in the GitHub ticket I've been linking to.

This has really nothing to do with in-process or out-of-process. Client-server databases also don't support this unfortunately, so SQlite isn't different here. I'm just complaining about the misleading docs.

PS: This is assuming we're talking about option 2), listening to all changes in-process. Option 3) does include some form of IPC, but since there's a rollback journal or WAL the information what changed from other processes exists in an efficient way anyway. I don't think SQLite's nature of being in-process makes this feature any more difficult to implement. It probably makes it easier.

((edited by admin to consolidate a mis-edit created before the initial post was moderator-approved. @John: you cannot edit your own posts until you have been approved to post without moderation (which you now how been).))

(8) By Gunter Hick (gunter_hick) on 2022-10-18 05:54:41 in reply to 7.1 [link] [source]

No, you cannot subscribe to changes in SQLite.

The sqlite3_xxx_hook() callbacks return information about what effects the statements YOU YOURSELF are executing on the database connection are having on the data. Think debugging and logging.