summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/CMakeLists.txt1
-rw-r--r--common/query.cpp56
-rw-r--r--common/query.h43
-rw-r--r--common/queryrunner.cpp10
-rw-r--r--common/resourcefacade.cpp7
-rw-r--r--common/store.cpp25
-rw-r--r--common/typeindex.cpp4
-rw-r--r--tests/clientapitest.cpp6
-rw-r--r--tests/dummyresourcebenchmark.cpp2
-rw-r--r--tests/dummyresourcetest.cpp38
-rw-r--r--tests/maildirresourcetest.cpp2
-rw-r--r--tests/mailquerybenchmark.cpp2
-rw-r--r--tests/querytest.cpp6
13 files changed, 151 insertions, 51 deletions
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index 54d86f3..c269a85 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -65,6 +65,7 @@ set(command_SRCS
65 domain/mail.cpp 65 domain/mail.cpp
66 domain/folder.cpp 66 domain/folder.cpp
67 test.cpp 67 test.cpp
68 query.cpp
68 ${storage_SRCS}) 69 ${storage_SRCS})
69 70
70add_library(${PROJECT_NAME} SHARED ${command_SRCS}) 71add_library(${PROJECT_NAME} SHARED ${command_SRCS})
diff --git a/common/query.cpp b/common/query.cpp
new file mode 100644
index 0000000..a80aecb
--- /dev/null
+++ b/common/query.cpp
@@ -0,0 +1,56 @@
1/*
2 * Copyright (C) 2014 Christian Mollekopf <chrigi_1@fastmail.fm>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) version 3, or any
8 * later version accepted by the membership of KDE e.V. (or its
9 * successor approved by the membership of KDE e.V.), which shall
10 * act as a proxy defined in Section 6 of version 3 of the license.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
19 */
20#include "query.h"
21
22using namespace Sink;
23
24QDebug operator<<(QDebug dbg, const Sink::Query::Comparator &c)
25{
26 if (c.comparator == Sink::Query::Comparator::Equals) {
27 dbg.nospace() << "== " << c.value;
28 } else if (c.comparator == Sink::Query::Comparator::Contains) {
29 dbg.nospace() << "contains " << c.value;
30 } else {
31 dbg.nospace() << "unknown comparator: " << c.value;
32 }
33
34 return dbg.space();
35}
36
37Query::Comparator::Comparator() : comparator(Invalid)
38{
39}
40
41Query::Comparator::Comparator(const QVariant &v) : value(v), comparator(Equals)
42{
43}
44
45bool Query::Comparator::matches(const QVariant &v) const
46{
47 switch(comparator) {
48 case Equals:
49 return v == value;
50 case Contains:
51 return v.toList().contains(value);
52 default:
53 break;
54 }
55 return false;
56}
diff --git a/common/query.h b/common/query.h
index 3a56c9f..ccac1e7 100644
--- a/common/query.h
+++ b/common/query.h
@@ -19,6 +19,7 @@
19 */ 19 */
20#pragma once 20#pragma once
21 21
22#include "sink_export.h"
22#include <QByteArrayList> 23#include <QByteArrayList>
23#include <QHash> 24#include <QHash>
24#include <QSet> 25#include <QSet>
@@ -29,7 +30,7 @@ namespace Sink {
29/** 30/**
30 * A query that matches a set of entities. 31 * A query that matches a set of entities.
31 */ 32 */
32class Query 33class SINK_EXPORT Query
33{ 34{
34public: 35public:
35 enum Flag 36 enum Flag
@@ -46,6 +47,13 @@ public:
46 return query; 47 return query;
47 } 48 }
48 49
50 static Query PropertyContainsFilter(const QByteArray &key, const QVariant &value)
51 {
52 Query query;
53 query.propertyFilter.insert(key, value);
54 return query;
55 }
56
49 static Query PropertyFilter(const QByteArray &key, const ApplicationDomain::Entity &entity) 57 static Query PropertyFilter(const QByteArray &key, const ApplicationDomain::Entity &entity)
50 { 58 {
51 return PropertyFilter(key, QVariant::fromValue(entity.identifier())); 59 return PropertyFilter(key, QVariant::fromValue(entity.identifier()));
@@ -70,6 +78,18 @@ public:
70 return ResourceFilter(entity.identifier()); 78 return ResourceFilter(entity.identifier());
71 } 79 }
72 80
81 static Query AccountFilter(const QByteArrayList &identifier)
82 {
83 Query query;
84 query.accounts = identifier;
85 return query;
86 }
87
88 static Query AccountFilter(const ApplicationDomain::SinkAccount &entity)
89 {
90 return AccountFilter(entity.identifier());
91 }
92
73 static Query IdentityFilter(const QByteArray &identifier) 93 static Query IdentityFilter(const QByteArray &identifier)
74 { 94 {
75 Query query; 95 Query query;
@@ -110,6 +130,7 @@ public:
110 Query &operator+=(const Query &rhs) 130 Query &operator+=(const Query &rhs)
111 { 131 {
112 resources += rhs.resources; 132 resources += rhs.resources;
133 accounts += rhs.accounts;
113 ids += rhs.ids; 134 ids += rhs.ids;
114 for (auto it = rhs.propertyFilter.constBegin(); it != rhs.propertyFilter.constEnd(); it++) { 135 for (auto it = rhs.propertyFilter.constBegin(); it != rhs.propertyFilter.constEnd(); it++) {
115 propertyFilter.insert(it.key(), it.value()); 136 propertyFilter.insert(it.key(), it.value());
@@ -128,9 +149,25 @@ public:
128 return lhs; 149 return lhs;
129 } 150 }
130 151
152 struct Comparator {
153 enum Comparators {
154 Invalid,
155 Equals,
156 Contains
157 };
158
159 Comparator();
160 Comparator(const QVariant &v);
161 bool matches(const QVariant &v) const;
162
163 QVariant value;
164 Comparators comparator;
165 };
166
131 QByteArrayList resources; 167 QByteArrayList resources;
168 QByteArrayList accounts;
132 QByteArrayList ids; 169 QByteArrayList ids;
133 QHash<QByteArray, QVariant> propertyFilter; 170 QHash<QByteArray, Comparator> propertyFilter;
134 QByteArrayList requestedProperties; 171 QByteArrayList requestedProperties;
135 QByteArray parentProperty; 172 QByteArray parentProperty;
136 QByteArray sortProperty; 173 QByteArray sortProperty;
@@ -139,4 +176,6 @@ public:
139}; 176};
140} 177}
141 178
179QDebug operator<<(QDebug dbg, const Sink::Query::Comparator &c);
180
142Q_DECLARE_OPERATORS_FOR_FLAGS(Sink::Query::Flags) 181Q_DECLARE_OPERATORS_FOR_FLAGS(Sink::Query::Flags)
diff --git a/common/queryrunner.cpp b/common/queryrunner.cpp
index bbaae7b..38fc779 100644
--- a/common/queryrunner.cpp
+++ b/common/queryrunner.cpp
@@ -382,9 +382,9 @@ QueryWorker<DomainType>::getFilter(const QSet<QByteArray> remainingFilters, cons
382 for (const auto &filterProperty : remainingFilters) { 382 for (const auto &filterProperty : remainingFilters) {
383 const auto property = domainObject->getProperty(filterProperty); 383 const auto property = domainObject->getProperty(filterProperty);
384 if (property.isValid()) { 384 if (property.isValid()) {
385 // TODO implement other comparison operators than equality 385 const auto comparator = query.propertyFilter.value(filterProperty);
386 if (property != query.propertyFilter.value(filterProperty)) { 386 if (!comparator.matches(property)) {
387 Trace() << "Filtering entity due to property mismatch on filter: " << filterProperty << property << ":" << query.propertyFilter.value(filterProperty); 387 Trace() << "Filtering entity due to property mismatch on filter: " << filterProperty << property << ":" << comparator.value;
388 return false; 388 return false;
389 } 389 }
390 } else { 390 } else {
@@ -445,10 +445,10 @@ QPair<qint64, qint64> QueryWorker<DomainType>::executeInitialQuery(
445 if (!query.parentProperty.isEmpty()) { 445 if (!query.parentProperty.isEmpty()) {
446 if (parent) { 446 if (parent) {
447 Trace() << "Running initial query for parent:" << parent->identifier(); 447 Trace() << "Running initial query for parent:" << parent->identifier();
448 modifiedQuery.propertyFilter.insert(query.parentProperty, parent->identifier()); 448 modifiedQuery.propertyFilter.insert(query.parentProperty, Query::Comparator(parent->identifier()));
449 } else { 449 } else {
450 Trace() << "Running initial query for toplevel"; 450 Trace() << "Running initial query for toplevel";
451 modifiedQuery.propertyFilter.insert(query.parentProperty, QVariant()); 451 modifiedQuery.propertyFilter.insert(query.parentProperty, Query::Comparator(QVariant()));
452 } 452 }
453 } 453 }
454 auto revisionAndReplayedEntities = load(modifiedQuery, [&](Sink::Storage::Transaction &transaction, QSet<QByteArray> &remainingFilters, QByteArray &remainingSorting) -> ResultSet { 454 auto revisionAndReplayedEntities = load(modifiedQuery, [&](Sink::Storage::Transaction &transaction, QSet<QByteArray> &remainingFilters, QByteArray &remainingSorting) -> ResultSet {
diff --git a/common/resourcefacade.cpp b/common/resourcefacade.cpp
index e6d235f..96e2ac3 100644
--- a/common/resourcefacade.cpp
+++ b/common/resourcefacade.cpp
@@ -113,13 +113,13 @@ KAsync::Job<void> LocalStorageFacade<DomainType>::remove(const DomainType &domai
113 }); 113 });
114} 114}
115 115
116static bool matchesFilter(const QHash<QByteArray, QVariant> &filter, const QMap<QByteArray, QVariant> &properties) 116static bool matchesFilter(const QHash<QByteArray, Sink::Query::Comparator> &filter, const QMap<QByteArray, QVariant> &properties)
117{ 117{
118 for (const auto &filterProperty : filter.keys()) { 118 for (const auto &filterProperty : filter.keys()) {
119 if (filterProperty == "type") { 119 if (filterProperty == "type") {
120 continue; 120 continue;
121 } 121 }
122 if (filter.value(filterProperty).toByteArray() != properties.value(filterProperty).toByteArray()) { 122 if (filter.value(filterProperty).matches(properties.value(filterProperty))) {
123 return false; 123 return false;
124 } 124 }
125 } 125 }
@@ -138,7 +138,8 @@ QPair<KAsync::Job<void>, typename Sink::ResultEmitter<typename DomainType::Ptr>:
138 const auto entries = mConfigStore.getEntries(); 138 const auto entries = mConfigStore.getEntries();
139 for (const auto &res : entries.keys()) { 139 for (const auto &res : entries.keys()) {
140 const auto type = entries.value(res); 140 const auto type = entries.value(res);
141 if (query.propertyFilter.contains("type") && query.propertyFilter.value("type").toByteArray() != type) { 141
142 if (query.propertyFilter.contains("type") && query.propertyFilter.value("type").value.toByteArray() != type) {
142 Trace() << "Skipping due to type."; 143 Trace() << "Skipping due to type.";
143 continue; 144 continue;
144 } 145 }
diff --git a/common/store.cpp b/common/store.cpp
index b89e08c..0ac99be 100644
--- a/common/store.cpp
+++ b/common/store.cpp
@@ -54,8 +54,16 @@ QString Store::getTemporaryFilePath()
54/* 54/*
55 * Returns a map of resource instance identifiers and resource type 55 * Returns a map of resource instance identifiers and resource type
56 */ 56 */
57static QMap<QByteArray, QByteArray> getResources(const QList<QByteArray> &resourceFilter, const QByteArray &type = QByteArray()) 57static QMap<QByteArray, QByteArray> getResources(const QList<QByteArray> &resourceFilter, const QList<QByteArray> &accountFilter,const QByteArray &type = QByteArray())
58{ 58{
59 const auto filterResource = [&](const QByteArray &res) {
60 const auto configuration = ResourceConfig::getConfiguration(res);
61 if (!accountFilter.isEmpty() && !accountFilter.contains(configuration.value("account").toByteArray())) {
62 return true;
63 }
64 return false;
65 };
66
59 QMap<QByteArray, QByteArray> resources; 67 QMap<QByteArray, QByteArray> resources;
60 // Return the global resource (signified by an empty name) for types that don't belong to a specific resource 68 // Return the global resource (signified by an empty name) for types that don't belong to a specific resource
61 if (type == "sinkresource" || type == "sinkaccount" || type == "identity") { 69 if (type == "sinkresource" || type == "sinkaccount" || type == "identity") {
@@ -65,15 +73,22 @@ static QMap<QByteArray, QByteArray> getResources(const QList<QByteArray> &resour
65 const auto configuredResources = ResourceConfig::getResources(); 73 const auto configuredResources = ResourceConfig::getResources();
66 if (resourceFilter.isEmpty()) { 74 if (resourceFilter.isEmpty()) {
67 for (const auto &res : configuredResources.keys()) { 75 for (const auto &res : configuredResources.keys()) {
76 const auto type = configuredResources.value(res);
77 if (filterResource(res)) {
78 continue;
79 }
68 // TODO filter by entity type 80 // TODO filter by entity type
69 resources.insert(res, configuredResources.value(res)); 81 resources.insert(res, type);
70 } 82 }
71 } else { 83 } else {
72 for (const auto &res : resourceFilter) { 84 for (const auto &res : resourceFilter) {
73 if (configuredResources.contains(res)) { 85 if (configuredResources.contains(res)) {
86 if (filterResource(res)) {
87 continue;
88 }
74 resources.insert(res, configuredResources.value(res)); 89 resources.insert(res, configuredResources.value(res));
75 } else { 90 } else {
76 qWarning() << "Resource is not existing: " << res; 91 Warning() << "Resource is not existing: " << res;
77 } 92 }
78 } 93 }
79 } 94 }
@@ -100,7 +115,7 @@ QSharedPointer<QAbstractItemModel> Store::loadModel(Query query)
100 //* The result provider needs to live for as long as results are provided (until the last thread exits). 115 //* The result provider needs to live for as long as results are provided (until the last thread exits).
101 116
102 // Query all resources and aggregate results 117 // Query all resources and aggregate results
103 auto resources = getResources(query.resources, ApplicationDomain::getTypeName<DomainType>()); 118 auto resources = getResources(query.resources, query.accounts, ApplicationDomain::getTypeName<DomainType>());
104 auto aggregatingEmitter = AggregatingResultEmitter<typename DomainType::Ptr>::Ptr::create(); 119 auto aggregatingEmitter = AggregatingResultEmitter<typename DomainType::Ptr>::Ptr::create();
105 model->setEmitter(aggregatingEmitter); 120 model->setEmitter(aggregatingEmitter);
106 KAsync::iterate(resources.keys()) 121 KAsync::iterate(resources.keys())
@@ -181,7 +196,7 @@ KAsync::Job<void> Store::removeDataFromDisk(const QByteArray &identifier)
181KAsync::Job<void> Store::synchronize(const Sink::Query &query) 196KAsync::Job<void> Store::synchronize(const Sink::Query &query)
182{ 197{
183 Trace() << "synchronize" << query.resources; 198 Trace() << "synchronize" << query.resources;
184 auto resources = getResources(query.resources).keys(); 199 auto resources = getResources(query.resources, query.accounts).keys();
185 return KAsync::iterate(resources) 200 return KAsync::iterate(resources)
186 .template each<void, QByteArray>([query](const QByteArray &resource, KAsync::Future<void> &future) { 201 .template each<void, QByteArray>([query](const QByteArray &resource, KAsync::Future<void> &future) {
187 Trace() << "Synchronizing " << resource; 202 Trace() << "Synchronizing " << resource;
diff --git a/common/typeindex.cpp b/common/typeindex.cpp
index 1321469..fca083c 100644
--- a/common/typeindex.cpp
+++ b/common/typeindex.cpp
@@ -143,7 +143,7 @@ ResultSet TypeIndex::query(const Sink::Query &query, QSet<QByteArray> &appliedFi
143 for (auto it = mSortedProperties.constBegin(); it != mSortedProperties.constEnd(); it++) { 143 for (auto it = mSortedProperties.constBegin(); it != mSortedProperties.constEnd(); it++) {
144 if (query.propertyFilter.contains(it.key()) && query.sortProperty == it.value()) { 144 if (query.propertyFilter.contains(it.key()) && query.sortProperty == it.value()) {
145 Index index(indexName(it.key(), it.value()), transaction); 145 Index index(indexName(it.key(), it.value()), transaction);
146 const auto lookupKey = getByteArray(query.propertyFilter.value(it.key())); 146 const auto lookupKey = getByteArray(query.propertyFilter.value(it.key()).value);
147 Trace() << "looking for " << lookupKey; 147 Trace() << "looking for " << lookupKey;
148 index.lookup(lookupKey, [&](const QByteArray &value) { keys << value; }, 148 index.lookup(lookupKey, [&](const QByteArray &value) { keys << value; },
149 [it](const Index::Error &error) { Warning() << "Error in index: " << error.message << it.key() << it.value(); }, true); 149 [it](const Index::Error &error) { Warning() << "Error in index: " << error.message << it.key() << it.value(); }, true);
@@ -156,7 +156,7 @@ ResultSet TypeIndex::query(const Sink::Query &query, QSet<QByteArray> &appliedFi
156 for (const auto &property : mProperties) { 156 for (const auto &property : mProperties) {
157 if (query.propertyFilter.contains(property)) { 157 if (query.propertyFilter.contains(property)) {
158 Index index(indexName(property), transaction); 158 Index index(indexName(property), transaction);
159 const auto lookupKey = getByteArray(query.propertyFilter.value(property)); 159 const auto lookupKey = getByteArray(query.propertyFilter.value(property).value);
160 index.lookup( 160 index.lookup(
161 lookupKey, [&](const QByteArray &value) { keys << value; }, [property](const Index::Error &error) { Warning() << "Error in index: " << error.message << property; }); 161 lookupKey, [&](const QByteArray &value) { keys << value; }, [property](const Index::Error &error) { Warning() << "Error in index: " << error.message << property; });
162 appliedFilters << property; 162 appliedFilters << property;
diff --git a/tests/clientapitest.cpp b/tests/clientapitest.cpp
index 172232f..96982ca 100644
--- a/tests/clientapitest.cpp
+++ b/tests/clientapitest.cpp
@@ -58,7 +58,7 @@ public:
58 } 58 }
59 Trace() << "-------------------------."; 59 Trace() << "-------------------------.";
60 for (const auto &res : results) { 60 for (const auto &res : results) {
61 qDebug() << "Parent filter " << query.propertyFilter.value("parent").toByteArray() << res->identifier() << res->getProperty("parent").toByteArray(); 61 qDebug() << "Parent filter " << query.propertyFilter.value("parent").value.toByteArray() << res->identifier() << res->getProperty("parent").toByteArray();
62 auto parentProperty = res->getProperty("parent").toByteArray(); 62 auto parentProperty = res->getProperty("parent").toByteArray();
63 if ((!parent && parentProperty.isEmpty()) || (parent && parentProperty == parent->identifier()) || query.parentProperty.isEmpty()) { 63 if ((!parent && parentProperty.isEmpty()) || (parent && parentProperty == parent->identifier()) || query.parentProperty.isEmpty()) {
64 qDebug() << "Found a hit" << res->identifier(); 64 qDebug() << "Found a hit" << res->identifier();
@@ -132,7 +132,7 @@ private slots:
132 Sink::Store::create(res).exec().waitForFinished(); 132 Sink::Store::create(res).exec().waitForFinished();
133 { 133 {
134 Sink::Query query; 134 Sink::Query query;
135 query.propertyFilter.insert("type", "dummyresource"); 135 query.propertyFilter.insert("type", Sink::Query::Comparator("dummyresource"));
136 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::SinkResource>(query); 136 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::SinkResource>(query);
137 QTRY_COMPARE(model->rowCount(QModelIndex()), 1); 137 QTRY_COMPARE(model->rowCount(QModelIndex()), 1);
138 } 138 }
@@ -140,7 +140,7 @@ private slots:
140 Sink::Store::remove(res).exec().waitForFinished(); 140 Sink::Store::remove(res).exec().waitForFinished();
141 { 141 {
142 Sink::Query query; 142 Sink::Query query;
143 query.propertyFilter.insert("type", "dummyresource"); 143 query.propertyFilter.insert("type", Sink::Query::Comparator("dummyresource"));
144 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::SinkResource>(query); 144 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::SinkResource>(query);
145 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 145 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
146 QCOMPARE(model->rowCount(QModelIndex()), 0); 146 QCOMPARE(model->rowCount(QModelIndex()), 0);
diff --git a/tests/dummyresourcebenchmark.cpp b/tests/dummyresourcebenchmark.cpp
index 1e71fc2..d5f98c3 100644
--- a/tests/dummyresourcebenchmark.cpp
+++ b/tests/dummyresourcebenchmark.cpp
@@ -157,7 +157,7 @@ private slots:
157 Sink::Query query; 157 Sink::Query query;
158 query.resources << "org.kde.dummy.instance1"; 158 query.resources << "org.kde.dummy.instance1";
159 159
160 query.propertyFilter.insert("uid", "testuid"); 160 query.propertyFilter.insert("uid", Sink::Query::Comparator("testuid"));
161 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query); 161 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query);
162 QTRY_COMPARE(model->rowCount(QModelIndex()), num); 162 QTRY_COMPARE(model->rowCount(QModelIndex()), num);
163 } 163 }
diff --git a/tests/dummyresourcetest.cpp b/tests/dummyresourcetest.cpp
index 33304e1..58df2da 100644
--- a/tests/dummyresourcetest.cpp
+++ b/tests/dummyresourcetest.cpp
@@ -12,6 +12,8 @@
12#include "pipeline.h" 12#include "pipeline.h"
13#include "log.h" 13#include "log.h"
14 14
15using namespace Sink;
16
15/** 17/**
16 * Test of complete system using the dummy resource. 18 * Test of complete system using the dummy resource.
17 * 19 *
@@ -62,14 +64,12 @@ private slots:
62 event.setProperty("summary", "summaryValue"); 64 event.setProperty("summary", "summaryValue");
63 Sink::Store::create<Sink::ApplicationDomain::Event>(event).exec().waitForFinished(); 65 Sink::Store::create<Sink::ApplicationDomain::Event>(event).exec().waitForFinished();
64 66
65 Sink::Query query; 67 const auto query = Query::ResourceFilter("org.kde.dummy.instance1") ;
66 query.resources << "org.kde.dummy.instance1";
67 68
68 // Ensure all local data is processed 69 // Ensure all local data is processed
69 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 70 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
70 71
71 query.propertyFilter.insert("uid", "testuid"); 72 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query + Query::PropertyFilter("uid", "testuid"));
72 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query);
73 QTRY_COMPARE(model->rowCount(QModelIndex()), 1); 73 QTRY_COMPARE(model->rowCount(QModelIndex()), 1);
74 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Event::Ptr>(); 74 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Event::Ptr>();
75 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid")); 75 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid"));
@@ -86,15 +86,12 @@ private slots:
86 event.setProperty("uid", "testuid2"); 86 event.setProperty("uid", "testuid2");
87 Sink::Store::create<Sink::ApplicationDomain::Event>(event).exec().waitForFinished(); 87 Sink::Store::create<Sink::ApplicationDomain::Event>(event).exec().waitForFinished();
88 88
89 Sink::Query query; 89 const auto query = Query::ResourceFilter("org.kde.dummy.instance1") ;
90 query.resources << "org.kde.dummy.instance1";
91 90
92 // Ensure all local data is processed 91 // Ensure all local data is processed
93 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 92 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
94 93
95 query.propertyFilter.insert("uid", "testuid"); 94 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query + Query::PropertyFilter("uid", "testuid"));
96
97 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query);
98 QTRY_COMPARE(model->rowCount(QModelIndex()), 1); 95 QTRY_COMPARE(model->rowCount(QModelIndex()), 1);
99 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Event::Ptr>(); 96 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Event::Ptr>();
100 97
@@ -114,15 +111,12 @@ private slots:
114 event.setProperty("summary", "summaryValue2"); 111 event.setProperty("summary", "summaryValue2");
115 Sink::Store::create<Sink::ApplicationDomain::Event>(event).exec().waitForFinished(); 112 Sink::Store::create<Sink::ApplicationDomain::Event>(event).exec().waitForFinished();
116 113
117 Sink::Query query; 114 const auto query = Query::ResourceFilter("org.kde.dummy.instance1") ;
118 query.resources << "org.kde.dummy.instance1";
119 115
120 // Ensure all local data is processed 116 // Ensure all local data is processed
121 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 117 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
122 118
123 query.propertyFilter.insert("summary", "summaryValue2"); 119 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query + Query::PropertyFilter("summary", "summaryValue2"));
124
125 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query);
126 QTRY_COMPARE(model->rowCount(QModelIndex()), 1); 120 QTRY_COMPARE(model->rowCount(QModelIndex()), 1);
127 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Event::Ptr>(); 121 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Event::Ptr>();
128 122
@@ -147,8 +141,7 @@ private slots:
147 141
148 void testSyncAndFacade() 142 void testSyncAndFacade()
149 { 143 {
150 Sink::Query query; 144 const auto query = Query::ResourceFilter("org.kde.dummy.instance1");
151 query.resources << "org.kde.dummy.instance1";
152 145
153 // Ensure all local data is processed 146 // Ensure all local data is processed
154 Sink::Store::synchronize(query).exec().waitForFinished(); 147 Sink::Store::synchronize(query).exec().waitForFinished();
@@ -164,8 +157,7 @@ private slots:
164 157
165 void testSyncAndFacadeMail() 158 void testSyncAndFacadeMail()
166 { 159 {
167 Sink::Query query; 160 const auto query = Query::ResourceFilter("org.kde.dummy.instance1");
168 query.resources << "org.kde.dummy.instance1";
169 161
170 // Ensure all local data is processed 162 // Ensure all local data is processed
171 Sink::Store::synchronize(query).exec().waitForFinished(); 163 Sink::Store::synchronize(query).exec().waitForFinished();
@@ -187,9 +179,7 @@ private slots:
187 event.setProperty("summary", "summaryValue"); 179 event.setProperty("summary", "summaryValue");
188 Sink::Store::create<Sink::ApplicationDomain::Event>(event).exec().waitForFinished(); 180 Sink::Store::create<Sink::ApplicationDomain::Event>(event).exec().waitForFinished();
189 181
190 Sink::Query query; 182 const auto query = Query::ResourceFilter("org.kde.dummy.instance1") + Query::PropertyFilter("uid", "testuid");
191 query.resources << "org.kde.dummy.instance1";
192 query.propertyFilter.insert("uid", "testuid");
193 183
194 // Ensure all local data is processed 184 // Ensure all local data is processed
195 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 185 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
@@ -238,11 +228,9 @@ private slots:
238 228
239 void testWriteModifyDeleteLive() 229 void testWriteModifyDeleteLive()
240 { 230 {
241 231 auto query = Query::ResourceFilter("org.kde.dummy.instance1");
242 Sink::Query query;
243 query.resources << "org.kde.dummy.instance1";
244 query.liveQuery = true; 232 query.liveQuery = true;
245 query.propertyFilter.insert("uid", "testuid"); 233 query += Query::PropertyFilter("uid", "testuid");
246 234
247 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query); 235 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query);
248 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 236 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
diff --git a/tests/maildirresourcetest.cpp b/tests/maildirresourcetest.cpp
index b5c1c3c..9b014e3 100644
--- a/tests/maildirresourcetest.cpp
+++ b/tests/maildirresourcetest.cpp
@@ -265,7 +265,7 @@ private slots:
265 265
266 Sink::Query folderQuery; 266 Sink::Query folderQuery;
267 folderQuery.resources << "org.kde.maildir.instance1"; 267 folderQuery.resources << "org.kde.maildir.instance1";
268 folderQuery.propertyFilter.insert("name", "testCreateFolder"); 268 folderQuery += Sink::Query::PropertyFilter("name", "testCreateFolder");
269 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Folder>(folderQuery); 269 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Folder>(folderQuery);
270 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 270 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
271 QCOMPARE(model->rowCount(QModelIndex()), 1); 271 QCOMPARE(model->rowCount(QModelIndex()), 1);
diff --git a/tests/mailquerybenchmark.cpp b/tests/mailquerybenchmark.cpp
index 6b93863..20ee63c 100644
--- a/tests/mailquerybenchmark.cpp
+++ b/tests/mailquerybenchmark.cpp
@@ -159,7 +159,7 @@ private slots:
159 << "subject" 159 << "subject"
160 << "date"; 160 << "date";
161 query.sortProperty = "date"; 161 query.sortProperty = "date";
162 query.propertyFilter.insert("folder", "folder1"); 162 query += Sink::Query::PropertyFilter("folder", "folder1");
163 query.limit = 1000; 163 query.limit = 1000;
164 164
165 populateDatabase(50000); 165 populateDatabase(50000);
diff --git a/tests/querytest.cpp b/tests/querytest.cpp
index 7b9129e..a654931 100644
--- a/tests/querytest.cpp
+++ b/tests/querytest.cpp
@@ -202,7 +202,7 @@ private slots:
202 Sink::Query query; 202 Sink::Query query;
203 query.resources << "org.kde.dummy.instance1"; 203 query.resources << "org.kde.dummy.instance1";
204 query.liveQuery = false; 204 query.liveQuery = false;
205 query.propertyFilter.insert("uid", "test1"); 205 query += Sink::Query::PropertyFilter("uid", "test1");
206 206
207 // Ensure all local data is processed 207 // Ensure all local data is processed
208 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 208 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
@@ -243,7 +243,7 @@ private slots:
243 // Test 243 // Test
244 Sink::Query query; 244 Sink::Query query;
245 query.resources << "org.kde.dummy.instance1"; 245 query.resources << "org.kde.dummy.instance1";
246 query.propertyFilter.insert("folder", folderEntity->identifier()); 246 query += Sink::Query::PropertyFilter("folder", *folderEntity);
247 247
248 // Ensure all local data is processed 248 // Ensure all local data is processed
249 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 249 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
@@ -302,7 +302,7 @@ private slots:
302 // Test 302 // Test
303 Sink::Query query; 303 Sink::Query query;
304 query.resources << "org.kde.dummy.instance1"; 304 query.resources << "org.kde.dummy.instance1";
305 query.propertyFilter.insert("folder", folderEntity->identifier()); 305 query += Sink::Query::PropertyFilter("folder", *folderEntity);
306 query.sortProperty = "date"; 306 query.sortProperty = "date";
307 query.limit = 1; 307 query.limit = 1;
308 query.liveQuery = false; 308 query.liveQuery = false;