4

I wrote a C++ program using Qt. some variables inside my algorithm are changed outside of my program and in a web page. every time the user changes the variable values in the web page I modify a pre-created SQL database. Now I want my code to change the variables value during run time without to stop the code. there is two options :

  1. Every n seconds check the database and retrieve the variables value -> this is not good since I have to check if database content is changed every n seconds (it might be without any change for years. Also I don't want to check if the database content is changed)

  2. Every time the database is changed my Qt program emits a signal so by catching this signal I can refresh the variables value, This seems an optimal solution and I want to write a code for this part

The C++ part of my code is:

void Update Database()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("localhost");
    db.setDatabaseName("Mydataset");

    db.setUserName("user");
    db.setPassword("pass");

    if(!db.open())
    {
        qDebug()<<"Error is: "<<db.lastError();
        qFatal("Failed To Connect");
    }
    QSqlQuery qry;
    qry.exec("SELECT * from tblsystemoptions");
    QSqlRecord rec = qry.record();
    int cols = rec.count();
    qry.next();
    MCH = qry.value(0).toString();  //some global variables used in other functions
    MCh = qry.value(1).toString();
    // ... this goes on ...


}
Stefan Becker
  • 5,695
  • 9
  • 20
  • 30

2 Answers2

13

QSqlDriver supports notifications which emit a signal when a specific event has occurred. To subscribe to an event just use QSqlDriver::subscribeToNotification( const QString & name ). When an event that you’re subscribing to is posted by the database the driver will emit the notification() signal and your application can take appropriate action.

db.driver()->subscribeToNotification("someEventId");

The message can be posted automatically from a trigger or a stored procedure. The message is very lightweight: nothing more than a string containing the name of the event that occurred.

You can connect the notification(const QString&)signal to your slot like:

QObject::connect(db.driver(), SIGNAL(notification(const QString&)), this, SLOT(refreshView()));

I should note that this feature is not supported by MySQL as it does not have an event posting mechanism.

Nejat
  • 31,784
  • 12
  • 106
  • 138
  • To be honest, i was not aware of this. This is actually pretty cool ... thanks a lot. +1 – OnWhenReady Apr 07 '14 at 18:01
  • Mhh ... are you sure that QMYSQL supports notifications because i do not find any evidence that MySQL supports this. I am just curious because i was surprised i was aware of this (if it is available) awesome feature. – OnWhenReady Apr 07 '14 at 18:39
  • Ok ... i have checked it and it does not work since MySQL (at least in version 5.5.32) does not support such a mechanism. I assume you did not test it? – OnWhenReady Apr 07 '14 at 20:07
  • 1
    Yeah it is not available for QMYSQL. I was not targeting MySQL. – Nejat Apr 08 '14 at 02:47
  • 1
    Ok. Maybe you should edit your answer since it is kind of unrelated to the question of OP who it clearly targeting MySQL. – OnWhenReady Apr 08 '14 at 04:00
  • Seems only PostgreSQL driver supports event notifications. The rest would require polling. – user3427419 Apr 08 '14 at 05:35
2

There is no such thing. The Qt event loop and the database are not connected in any way. You only fetch/alter/delete/insert/... data and that's it. Option 1 is the one you have to do. There are ways to use TRIGGER on the server side to launch external scripts but this would not help you very much.

OnWhenReady
  • 939
  • 6
  • 15
  • the external script could connect with the Qt app and that can then trigger a signal but that is quite a bit of work – ratchet freak Apr 07 '14 at 15:38
  • Yeah. But the question here is: How should it connect? Per socket? If the server is not under heavy load and the data you try to fetch is a cheap select, i would do a timed fetch. Everything else is rather complicated. I think OP needs a push-notification service ;-) – OnWhenReady Apr 07 '14 at 15:45
  • Dear DOminik is it possible by using sockets ? I think it's easy both in php and qt to communicate through a socket isn't it ? –  Apr 07 '14 at 15:58
  • I am by far no expert on php but using sockets will only shift the problem because you have to constantly connect to a server that will notify you (e.g. by writing to the socket) that something changed. I do not know the type of app and the restrictions you are facing. But fetching e.g. a timestamp in a table and compare it to the local timing of your machine is by far a much more easy job than using a socket to communicate to a app that must be triggered by the databases. But i do not know the requirements of your task. Are you having bandwidth limits, complex selects to get the elements,...? – OnWhenReady Apr 07 '14 at 16:06
  • No it's just a simple table with just bunch of data ... both of this application run in a single pc and they can interact with each other thorough system RAM .... I've heard that sockets are a good candidate for my problem but I don't know anything about its efficiency ... –  Apr 07 '14 at 16:14
  • What's the second application? I think i don't get it? You have two applications that do inter-process communication and a sql-server on the same machine? – OnWhenReady Apr 07 '14 at 16:29