Add payload to QSqlDriver notification with PSQL implementation.
authorMatt Newell <newellm@blur.com>
Thu, 22 Mar 2012 17:42:56 +0000 (10:42 -0700)
committerQt by Nokia <qt-info@nokia.com>
Sat, 31 Mar 2012 06:40:55 +0000 (08:40 +0200)
Postgres async notifications can contain a payload parameter
that is currently discarded. This patch provides the QSqlDriver
api change necessary to deliver a payload with each emitted
notification by adding a QVariant parameter to the notification
signal. It also provides the implementation for the qsqlpsql driver.
The qsql_ibase driver has been updated to reflect the change to the
notification signal signature.

The eventNotificationPSQL test in the qsqldatabase test has
been expanded to test proper payload sending and receiving.
All tests/auto/sql/kernel tests have been run with sqllite and
postgres with no regressions.

Task-number: QTBUG-13500
Change-Id: I9137f6acc8cfca93f45791ca930e0287d93d5d0d
Reviewed-by: Mark Brand <mabrand@mabrand.nl>
src/sql/drivers/ibase/qsql_ibase.cpp
src/sql/drivers/psql/qsql_psql.cpp
src/sql/kernel/qsqldriver.cpp
src/sql/kernel/qsqldriver.h
tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp

index 1109dfd..19722ac 100644 (file)
@@ -1847,7 +1847,7 @@ void QIBaseDriver::qHandleEventNotification(void *updatedResultBuffer)
 
             if (eBuffer->subscriptionState == QIBaseEventBuffer::Subscribed) {
                 emit notification(i.key());
-                emit notification(i.key(), QSqlDriver::UnknownSource);
+                emit notification(i.key(), QSqlDriver::UnknownSource, QVariant());
             }
             else if (eBuffer->subscriptionState == QIBaseEventBuffer::Starting)
                 eBuffer->subscriptionState = QIBaseEventBuffer::Subscribed;
index 10374bb..de7aa5e 100644 (file)
@@ -1377,9 +1377,14 @@ void QPSQLDriver::_q_handleNotification(int)
     while((notify = PQnotifies(d->connection)) != 0) {
         QString name(QLatin1String(notify->relname));
         if (d->seid.contains(name)) {
+            QString payload;
+#if defined PG_VERSION_NUM && PG_VERSION_NUM-0 >= 70400
+            if (notify->extra)
+                payload = d->isUtf8 ? QString::fromUtf8(notify->extra) : QString::fromAscii(notify->extra);
+#endif
             emit notification(name);
             QSqlDriver::NotificationSource source = (notify->be_pid == PQbackendPID(d->connection)) ? QSqlDriver::SelfSource : QSqlDriver::OtherSource;
-            emit notification(name, source);
+            emit notification(name, source, payload);
         }
         else
             qWarning("QPSQLDriver: received notification for '%s' which isn't subscribed to.",
index 7e6a7f7..9a4732b 100644 (file)
@@ -133,10 +133,11 @@ QSqlDriver::~QSqlDriver()
 /*!
     \since 5.0
 
-    \fn QSqlDriver::notification(const QString &name, NotificationSource source)
+    \fn QSqlDriver::notification(const QString &name, NotificationSource source, const QString & payload)
 
     This signal is emitted when the database posts an event notification
-    that the driver subscribes to. \a name identifies the event notification, \a source indicates the signal source.
+    that the driver subscribes to. \a name identifies the event notification, \a source indicates the signal source,
+    \a payload holds the extra data optionally delivered with the notification.
 
     \sa subscribeToNotification()
 */
index 3ca8092..cf293cd 100644 (file)
@@ -122,7 +122,7 @@ public:
 
 Q_SIGNALS:
     void notification(const QString &name);
-    void notification(const QString &name, QSqlDriver::NotificationSource source);
+    void notification(const QString &name, QSqlDriver::NotificationSource source, const QVariant &payload);
 
 protected:
     virtual void setOpen(bool o);
index 992df6e..626c504 100644 (file)
@@ -2069,15 +2069,17 @@ void tst_QSqlDatabase::eventNotificationPSQL()
 
     QSqlQuery query(db);
     QString procedureName = qTableName("posteventProc", __FILE__);
+    QString payload = "payload";
     QSqlDriver &driver=*(db.driver());
     QVERIFY_SQL(driver, subscribeToNotification(procedureName));
-    QSignalSpy spy(db.driver(), SIGNAL(notification(const QString&,QSqlDriver::NotificationSource)));
-    query.exec(QString("NOTIFY \"%1\"").arg(procedureName));
+    QSignalSpy spy(db.driver(), SIGNAL(notification(const QString&,QSqlDriver::NotificationSource,const QVariant&)));
+    query.exec(QString("NOTIFY \"%1\", '%2'").arg(procedureName).arg(payload));
     QCoreApplication::processEvents();
     QCOMPARE(spy.count(), 1);
     QList<QVariant> arguments = spy.takeFirst();
-    QVERIFY(arguments.at(0).toString() == procedureName);
-    QVERIFY(qVariantValue<QSqlDriver::NotificationSource>(arguments.at(1)) == QSqlDriver::SelfSource);
+    QCOMPARE(arguments.at(0).toString(), procedureName);
+    QCOMPARE(qVariantValue<QSqlDriver::NotificationSource>(arguments.at(1)), QSqlDriver::SelfSource);
+    QCOMPARE(qvariant_cast<QVariant>(arguments.at(2)).toString(), payload);
     QVERIFY_SQL(driver, unsubscribeFromNotification(procedureName));
 }