Comments (3)
I'm not sure whether or not it makes sense to add some wrapper for this into SOCI, but in case anyone needs it, is it possible to do it "alongside" SOCI by leveraging the libpq backend. This should also give some idea of what would need to be done if anyone ever wanted to implement this for SOCI; the libpqxx
library appears to have a reasonable implementation, so that might be a good model.
- Call
LISTEN
on each channel, and keep track of what you want to receive each channel - Get a pointer to the
soci::postgresql_session_backend
, for example:
// dynamic_cast fails with "undefined reference to `typeinfo for soci::postgresql_session_backend'"
// I'm not clear on why, but the documentation also uses static_cast.
// Seems to be something about visibility and shared libraries.
// Not sure if it's the same thing, but in https://github.com/SOCI/soci/pull/975
// they changed away from dynamic_cast to fix some other issue.
auto *backend = static_cast< // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
soci::postgresql_session_backend *>(
sql_->get_backend());
- Optionally get the file descriptor by calling
PQsocket(backend->conn_)
; you can use this to listen asynchronously for changes however you like (e.g.select
,poll
,QSocketNotifier
) - When the socket is notified for read, or periodically, check for updates; something like this, but the exact details depend on your implementation:
/*
* "A better way to check for NOTIFY messages when you have no useful
* commands to execute is to call PQconsumeInput , then check PQnotifies.
* You can use select() to wait for data to arrive from the server,
* thereby using no CPU power unless there is something to do.
* (See PQsocket to obtain the file descriptor number to use with
* select().)"
*/
PQconsumeInput(impl_->postgresql_session_backend_->conn_);
/*
* "The function PQnotifies returns the next notification from a list of
* unhandled notification messages received from the server. It returns a
* null pointer if there are no pending notifications. Once a notification
* is returned from PQnotifies, it is considered handled and will be
* removed from the list of notifications."
*/
// We have to call PQfreemem after PQnotifies returns non-null;
// use unique_ptr with deleter to try to be exception-safe.
std::unique_ptr<PGnotify, decltype(&PQfreemem)> notifyPointer(nullptr, PQfreemem);
while (auto *notify = PQnotifies(impl_->postgresql_session_backend_->conn_)) {
notifyPointer.reset(notify);
if (auto it = impl_->receivers.find(notify->relname); it != impl_->receivers.end()) {
(*(it->second))(notify->extra, notify->be_pid);
}
}
- Make sure you re-send the
LISTEN
SQL if SOCI reconnects
References:
- https://www.postgresql.org/docs/current/libpq-notify.html
- https://www.postgresql.org/docs/current/libpq-example.html#LIBPQ-EXAMPLE-2
- libpqxx Notifications and Receivers
from soci.
It should be possible to use it directly, shouldn't it? I.e. wouldn't just issuing the corresponding SQL work?
But SOCI doesn't provide any special support for it as I don't know if any other RDBMS provide anything similar. If they do, we could try to find some useful API that could be implemented for all of them, but as long as it's just available in Postgres, it doesn't seem really useful to do anything special for it in SOCI, what would be the added value of doing this?
from soci.
It should be possible to use it directly, shouldn't it? I.e. wouldn't just issuing the corresponding SQL work?
I am not sure tbh as this is async. LISTEN registers a callback channel from how I understand it :)
From the docs:
With the libpq library, the application issues LISTEN as an ordinary SQL command, and then must periodically call the function PQnotifies to find out whether any notification events have been received. Other interfaces such as libpgtcl provide higher-level methods for handling notify events; indeed, with libpgtcl the application programmer should not even issue LISTEN or UNLISTEN directly.
So at least they have some sort of interface for this. So I am not sure if SOCI can do that in any way. The registration of it using the SQL command is only one half of this command from what I understand.
So unless I am mistaken, at least a polling or so is needed in the pg driver to use it.
I am not sure if any of the other supported Database backends provide anything like this.
Sqlite most certainly does not.
Mysql doesn't seem to have this either. At least, a quick google didn't yield results.
For oracle I am not sure as I only am able to find java results and my java isnt good enough to differentiate it from a java or a db listener thing.
Firebird sql seems to have something similar https://firebirdsql.org/file/documentation/papers_presentations/Power_Firebird_events.pdf
DB2 only has update events it seems https://www.ibm.com/docs/en/db2/11.5?topic=events-rowupdated no generic/user defined ones
ODBC seems to not support this or I wasnt able to find it.
from soci.
Related Issues (20)
- SOCI doesn't support automatic type conversion HOT 14
- Spelling mistake "execude_hardcoded" HOT 1
- "foreign_keys" does not work (SQLite) HOT 18
- soci 4.0 build Oracle backend on Windows HOT 6
- CMake installation issues with soci as a dependency HOT 2
- Add a `db_json` in the enum HOT 1
- fsanitize=undefined in parent project causes to link due to missing rtti infos in soci.so HOT 3
- Getting multiple recordsets from a stored procedure
- SOCI doesn't compile when using the `UNICODE` flag on Windows HOT 4
- Next release
- vcpkg soci crashes on session::close() HOT 1
- Streamline cmake usage HOT 14
- How to read DATETIME(3) type in database? HOT 2
- Missing backend includes HOT 2
- failed to connect to mysql database after I upgrade the mariadbclient library inside the msys2 HOT 2
- MSVC: number of sections exceeded object file format limit
- Issue with Boost 1.84 HOT 6
- Incorrect query result with `use` and `into` into vector, at least for sqlite3. HOT 1
- Incorrect query result with `use` and `into` into vector, at least for sqlite3. HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from soci.