summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Simons <kevin.simons@nokia.com>2012-03-22 22:37:09 +0100
committerQt by Nokia <qt-info@nokia.com>2012-03-23 11:12:31 +0100
commit0cccd2a43899afbf212f0357b36a91ab0aa84cda (patch)
tree4cfb6f159469efba2f8c52619214564b9559cbf5
parentf2b546dab332214d02204f07bf9213eb48f5c470 (diff)
Support arbitrary JSON terms in "contains" queries
Fixes Bug #3395. Change-Id: I1cb9859aba5d557af456aa90880a39a8f30c4d09 Reviewed-by: Jamey Hicks <jamey.hicks@nokia.com> Reviewed-by: Denis Dzyubenko <denis.dzyubenko@nokia.com>
-rw-r--r--src/daemon/jsondbquery.cpp53
-rw-r--r--tests/auto/queries/dataset.json17
-rw-r--r--tests/auto/queries/testjsondbqueries.cpp24
3 files changed, 91 insertions, 3 deletions
diff --git a/src/daemon/jsondbquery.cpp b/src/daemon/jsondbquery.cpp
index 4e29930..be38e2c 100644
--- a/src/daemon/jsondbquery.cpp
+++ b/src/daemon/jsondbquery.cpp
@@ -41,6 +41,8 @@
#include <QDebug>
#include <QFile>
+#include <QJsonDocument>
+#include <QStack>
#include <QString>
#include <QStringList>
@@ -341,6 +343,57 @@ JsonDbQuery *JsonDbQuery::parse(const QString &query, const QJsonObject &binding
term.regExp().setCaseSensitivity(Qt::CaseInsensitive);
//qDebug() << "pattern" << tvs.mid(2, eor-2);
term.regExp().setPattern(tvs.mid(2, eor-2));
+ } else if (op == "contains") {
+ bool ok = true;;
+
+ QString value = tokenizer.pop();
+ if (value == "[" || value == "{") {
+ QStack<QString> tokenStack;
+ tokenStack.push(value);
+ QString tkn = value;
+
+ while (ok && !tkn.isEmpty()) {
+ tkn = tokenizer.pop();
+ if (tkn == "]" && tokenStack.isEmpty()) {
+ tokenizer.push(tkn);
+ break;
+ } else {
+ value += tkn;
+ if (tkn == "]") {
+ if (tokenStack.pop() != "[")
+ ok = false;
+ } else if (tkn == "}") {
+ if (tokenStack.pop() != "{")
+ ok = false;
+ }
+ }
+ }
+
+ if (ok) {
+ QJsonParseError parserError;
+ QJsonDocument parsedValue = QJsonDocument::fromJson(value.toUtf8(), &parserError);
+ if (parserError.error != QJsonParseError::NoError) {
+ ok = false;
+ } else {
+ if (parsedValue.isArray())
+ term.setValue(parsedValue.array());
+ else
+ term.setValue(parsedValue.object());
+ }
+ }
+ } else {
+ parseJsonLiteral(value, &term, bindings, &ok);
+ }
+
+ if (!ok) {
+ parsedQuery->queryExplanation.append(QString("Failed to parse query value '%1' in query '%2' %3 op %4")
+ .arg(value)
+ .arg(parsedQuery->query)
+ .arg(fieldSpec)
+ .arg(op));
+ parseError = true;
+ break;
+ }
} else if ((op != "exists") && (op != "notExists")) {
QString value = tokenizer.pop();
bool ok = true;;
diff --git a/tests/auto/queries/dataset.json b/tests/auto/queries/dataset.json
index 8585e44..7697e29 100644
--- a/tests/auto/queries/dataset.json
+++ b/tests/auto/queries/dataset.json
@@ -18,8 +18,6 @@
"num-demon-bunnies":3,
"num-russian-bunnies":2
},
-
-
{
"_type" : "dragon",
"name": "marcia d'arcy",
@@ -151,5 +149,20 @@
"name": "thomas reim",
"type":"russian",
"age": 8
+ },
+ {
+ "_type" : "dog",
+ "name" : "rover",
+ "friends" : ["spike", "reggie"]
+ },
+ {
+ "_type" : "dog",
+ "name" : "spike",
+ "friends" : [ { "name" : "rover", "dog" : true }, { "name" : "puffy", "dog" : false } ]
+ },
+ {
+ "_type" : "dog",
+ "name" : "reggie",
+ "friends" : [ ["larrry", "curly", "moe"], ["spike", "rover"] ]
}
]
diff --git a/tests/auto/queries/testjsondbqueries.cpp b/tests/auto/queries/testjsondbqueries.cpp
index 700c132..d5218b6 100644
--- a/tests/auto/queries/testjsondbqueries.cpp
+++ b/tests/auto/queries/testjsondbqueries.cpp
@@ -98,6 +98,7 @@ private slots:
void queryNotEqual();
void queryQuotedProperties();
void querySortedByIndexName();
+ void queryContains();
void queryInvalid();
private:
@@ -427,10 +428,31 @@ void TestJsonDbQueries::querySortedByIndexName()
QVERIFY(confirmEachObject(queryResult.data, CheckSortOrder<double>("age", QList<double>() << 8 << 8 << 6 << 6 << 4 << 4 << 2 << 2 << 0 << 0)));
}
+void TestJsonDbQueries::queryContains()
+{
+ JsonDbQueryResult queryResult = find(mOwner, QLatin1String("[?_type = \"dog\"][?friends contains \"spike\" ]"));
+ QVERIFY(queryResult.error.isNull());
+ QCOMPARE(queryResult.data.count(), 1);
+ queryResult = find(mOwner, QLatin1String("[?_type = \"dog\"][?friends contains { \"name\" : \"puffy\", \"dog\" : false } ]"));
+ QVERIFY(queryResult.error.isNull());
+ QCOMPARE(queryResult.data.count(), 1);
+ queryResult = find(mOwner, QLatin1String("[?_type = \"dog\"][?friends contains [\"spike\", \"rover\"] ]"));
+ QVERIFY(queryResult.error.isNull());
+ QCOMPARE(queryResult.data.count(), 1);
+
+ // invalid queries
+ queryResult = find(mOwner, QLatin1String("[?_type = \"dog\"][?friends contains { \"name\" : \"puffy\" \"dog\" : false } ]"));
+ QVERIFY(!queryResult.error.isNull());
+ queryResult = find(mOwner, QLatin1String("[?_type = \"dog\"][?friends contains [\"spike\", \"rover\" ]"));
+ QVERIFY(!queryResult.error.isNull());
+ queryResult = find(mOwner, QLatin1String("[?_type = \"dog\"][?friends contains \"spike\", \"rover\" ] ]"));
+ QVERIFY(!queryResult.error.isNull());
+}
+
void TestJsonDbQueries::queryInvalid()
{
JsonDbQueryResult queryResult = find(mOwner, QLatin1String("foo"));
- QVERIFY(queryResult.data.isEmpty());
+ QVERIFY(!queryResult.error.isNull());
}
QTEST_MAIN(TestJsonDbQueries)