-
Notifications
You must be signed in to change notification settings - Fork 480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for Postgresql LISTEN command? #1101
Comments
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? |
I am not sure tbh as this is async. LISTEN registers a callback channel from how I understand it :) From the docs:
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. |
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
// 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());
/*
* "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);
}
}
References: |
Hi Postgresql has the non standard LISTEN command which allows to essentially have like a callback or event listener style interface to the database. https://www.postgresql.org/docs/current/sql-listen.html
Is there any chance that this might be supported in the future? Or is it already possible in some way I am not aware of? :)
The text was updated successfully, but these errors were encountered: