Code Monkey home page Code Monkey logo

Comments (3)

samh avatar samh commented on June 9, 2024 1

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.

  1. Call LISTEN on each channel, and keep track of what you want to receive each channel
  2. 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());
  1. 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)
  2. 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);
	}
}
  1. Make sure you re-send the LISTEN SQL if SOCI reconnects

References:

  1. https://www.postgresql.org/docs/current/libpq-notify.html
  2. https://www.postgresql.org/docs/current/libpq-example.html#LIBPQ-EXAMPLE-2
  3. libpqxx Notifications and Receivers

from soci.

vadz avatar vadz commented on June 9, 2024

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.

MTRNord avatar MTRNord commented on June 9, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.