summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Dzyubenko <denis.dzyubenko@nokia.com>2012-06-05 16:14:06 +0200
committerQt by Nokia <qt-info@nokia.com>2012-06-08 12:02:21 +0200
commit72eb7cda976c05c67616e93403750442175af430 (patch)
treea6821c982796ae590c1b0438624c32e593a27452
parentc85268e04d2f52d2aaecba9e927c1025a0f4648d (diff)
Fixed created QJsonDbWatcher with invalid state number
if the state number is too far in the future, or the partition is not available, or the watcher spans multiple object tables, report an error to the caller. Change-Id: I4b1e4fa2859b1e781f5b3d70e639c70fab1ae2db Reviewed-by: Jamey Hicks <jamey.hicks@nokia.com>
-rw-r--r--src/daemon/dbserver.cpp49
-rw-r--r--tests/auto/qjsondbwatcher/partitions.json3
-rw-r--r--tests/auto/qjsondbwatcher/testqjsondbwatcher.cpp53
-rw-r--r--tests/shared/testhelper.cpp6
4 files changed, 104 insertions, 7 deletions
diff --git a/src/daemon/dbserver.cpp b/src/daemon/dbserver.cpp
index fc3fa29..8cdc646 100644
--- a/src/daemon/dbserver.cpp
+++ b/src/daemon/dbserver.cpp
@@ -818,7 +818,7 @@ void DBServer::createNotification(const JsonDbObject &object, ClientJsonStream *
JsonDbQuery parsedQuery = parser.result();
JsonDbNotification *n = new JsonDbNotification(getOwner(stream), parsedQuery, actions);
- if (object.contains("initialStateNumber") && object.value("initialStateNumber").isDouble())
+ if (object.value("initialStateNumber").isDouble())
n->setInitialStateNumber(static_cast<qint32>(object.value("initialStateNumber").toDouble()));
stream->addNotification(uuid, n);
@@ -865,14 +865,53 @@ JsonDbError::ErrorCode DBServer::validateNotification(const JsonDbObject &notifi
return JsonDbError::MissingQuery;
}
- if (notificationDef.contains(JsonDbString::kPartitionStr) &&
- notificationDef.value(JsonDbString::kPartitionStr).toString() != mEphemeralPartition->name()) {
- QString partitionName = notificationDef.value(JsonDbString::kPartitionStr).toString();
+ QString partitionName = mDefaultPartition->partitionSpec().name;
+ QJsonValue v = notificationDef.value(JsonDbString::kPartitionStr);
+ if (!v.isUndefined()) {
+ if (!v.isString()) {
+ message = QStringLiteral("invalid partition specified");
+ return JsonDbError::InvalidPartition;
+ } else if (!v.toString().isEmpty()) {
+ partitionName = v.toString();
+ }
+ }
+ v = notificationDef.value(QStringLiteral("initialStateNumber"));
+ if (!v.isUndefined() && !v.isDouble()) {
+ message = QStringLiteral("invalid initial state number specified");
+ return JsonDbError::InvalidStateNumber;
+ }
+ quint32 initialStateNumber = static_cast<quint32>(v.toDouble(0));
+
+ if (partitionName != mEphemeralPartition->name()) {
JsonDbPartition *partition = findPartition(partitionName);
if (!partition) {
- message = QString::fromLatin1("Invalid partition specified: %1").arg(partitionName);
+ message = QStringLiteral("Invalid partition specified: %1").arg(partitionName);
+ return JsonDbError::InvalidPartition;
+ }
+ if (!partition->isOpen()) {
+ message = QStringLiteral("Partition '%1' is not currently available").arg(partitionName);
return JsonDbError::InvalidPartition;
}
+ JsonDbObjectTable *table = 0;
+ QSet<QString> matchedTypes = query.matchedTypes();
+ if (!matchedTypes.isEmpty()) {
+ foreach (const QString &type, matchedTypes) {
+ JsonDbObjectTable *viewtable = partition->findObjectTable(type);
+ if (table && viewtable && table != viewtable) {
+ message = QStringLiteral("Cannot create a watcher for multiple object tables");
+ return JsonDbError::MissingQuery;
+ }
+ table = viewtable;
+ }
+ }
+ if (!table)
+ table = partition->mainObjectTable();
+ if (initialStateNumber != static_cast<quint32>(-1)) {
+ if (initialStateNumber > table->stateNumber()) {
+ message = QStringLiteral("Too new state number specified");
+ return JsonDbError::InvalidStateNumber;
+ }
+ }
}
return JsonDbError::NoError;
diff --git a/tests/auto/qjsondbwatcher/partitions.json b/tests/auto/qjsondbwatcher/partitions.json
index f8a7c87..4619bc6 100644
--- a/tests/auto/qjsondbwatcher/partitions.json
+++ b/tests/auto/qjsondbwatcher/partitions.json
@@ -1,3 +1,4 @@
[
- { "name" :"com.qt-project.shared", "path":".", "default" : true }
+ { "name" :"com.qt-project.shared", "path":".", "default" : true },
+ { "name" :"com.qt-project.removable", "path":"/nonexistentdir", "removable" : true }
]
diff --git a/tests/auto/qjsondbwatcher/testqjsondbwatcher.cpp b/tests/auto/qjsondbwatcher/testqjsondbwatcher.cpp
index 66ff74a..cb465cc 100644
--- a/tests/auto/qjsondbwatcher/testqjsondbwatcher.cpp
+++ b/tests/auto/qjsondbwatcher/testqjsondbwatcher.cpp
@@ -870,6 +870,59 @@ void TestQJsonDbWatcher::invalid()
mConnection->addWatcher(&watcher3);
QVERIFY(waitForError(&watcher3, QJsonDbWatcher::InvalidPartition));
mConnection->removeWatcher(&watcher3);
+
+ // invalid initial state number
+ QJsonDbWatcher watcher4;
+ watcher4.setQuery(QStringLiteral("[?_type=\"Contact\"]"));
+ watcher4.setInitialStateNumber(1234567);
+ mConnection->addWatcher(&watcher4);
+ QVERIFY(waitForError(&watcher4, QJsonDbWatcher::InvalidStateNumber));
+ mConnection->removeWatcher(&watcher4);
+
+ // unavailable partition
+ QJsonDbWatcher watcher5;
+ watcher5.setQuery(QStringLiteral("[?_type=\"Contact\"]"));
+ watcher5.setPartition(QStringLiteral("com.qt-project.removable"));
+ mConnection->addWatcher(&watcher5);
+ QVERIFY(waitForError(&watcher5, QJsonDbWatcher::InvalidPartition));
+ mConnection->removeWatcher(&watcher5);
+
+ // watcher over multiple object tables
+ {
+ static const char schemaJson[] =
+"{ \
+ \"_type\": \"_schemaType\", \
+ \"name\": \"invalidMapType\", \
+ \"schema\": { \
+ \"type\": \"object\", \
+ \"extends\": {\"$ref\": \"View\"} \
+ } \
+}";
+ QJsonDbObject schema = QJsonDocument::fromJson(QByteArray(schemaJson)).object();
+
+ QJsonDbObject map;
+ map.insert(QLatin1String("_type"), QLatin1String("Map"));
+ map.insert(QLatin1String("targetType"), QLatin1String("invalidMapType"));
+ QJsonObject submap;
+ submap.insert(QLatin1String("com.test.indextest"), QLatin1String("function (o) { jsondb.emit(o); }"));
+ map.insert(QLatin1String("join"), submap);
+
+ QJsonDbCreateRequest request(QList<QJsonObject>() << schema << map);
+ QVERIFY(mConnection->send(&request));
+ QVERIFY(waitForResponse(&request));
+ QJsonDbWatcher watcher6;
+ watcher6.setQuery(QStringLiteral("[?_type=\"Contact\" | _type = \"invalidMapType\"]"));
+ mConnection->addWatcher(&watcher6);
+ QVERIFY(waitForError(&watcher6, QJsonDbWatcher::MissingQuery));
+ mConnection->removeWatcher(&watcher6);
+ }
+
+ // watcher over multiple types in the same object table
+ QJsonDbWatcher watcher7;
+ watcher7.setQuery(QStringLiteral("[?_type in [\"Contact\", \"AnotherContact\"]]"));
+ mConnection->addWatcher(&watcher7);
+ QVERIFY(waitForStatus(&watcher7, QJsonDbWatcher::Active));
+ mConnection->removeWatcher(&watcher7);
}
void TestQJsonDbWatcher::privatePartition()
diff --git a/tests/shared/testhelper.cpp b/tests/shared/testhelper.cpp
index b0dcd7c..346c4bb 100644
--- a/tests/shared/testhelper.cpp
+++ b/tests/shared/testhelper.cpp
@@ -376,7 +376,11 @@ bool TestHelper::waitForStatus(QJsonDbWatcher *watcher, QJsonDbWatcher::Status s
connect(watcher, SIGNAL(statusChanged(QtJsonDb::QJsonDbWatcher::Status)),
this, SLOT(watcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status)));
+ connect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)),
+ this, SLOT(watcherError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)));
blockWithTimeout();
+ disconnect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)),
+ this, SLOT(watcherError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)));
disconnect(watcher, SIGNAL(statusChanged(QtJsonDb::QJsonDbWatcher::Status)),
this, SLOT(watcherStatusChanged(QtJsonDb::QJsonDbWatcher::Status)));
@@ -519,7 +523,7 @@ void TestHelper::watcherLastStateNumberChanged(int stateNumber)
void TestHelper::watcherError(QtJsonDb::QJsonDbWatcher::ErrorCode code, QString msg)
{
- qWarning() << "Watcher error:" << code << msg;
+ Q_UNUSED(msg);
mReceivedError = code;
if (code == mExpectedError)
mEventLoop.quit();