summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-09-27 16:15:44 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-09-27 16:15:44 +0200
commit5830d7e0d1d35494823f5fa61a4871b8d9df1c9d (patch)
tree1383d9b6ad926a97ee8376175c6bee01182dc096
parent529db49c496f4f668cec3f7c59d2d0ec78c50c9a (diff)
downloadsink-5830d7e0d1d35494823f5fa61a4871b8d9df1c9d.tar.gz
sink-5830d7e0d1d35494823f5fa61a4871b8d9df1c9d.zip
Use the Query::filter api.
-rw-r--r--common/datastorequery.cpp31
-rw-r--r--common/query.h108
-rw-r--r--common/test.cpp2
-rw-r--r--sinksh/syntax_modules/sink_list.cpp4
-rw-r--r--tests/clientapitest.cpp2
-rw-r--r--tests/dummyresourcetest.cpp96
-rw-r--r--tests/mailquerybenchmark.cpp31
-rw-r--r--tests/mailtest.cpp39
-rw-r--r--tests/mailthreadtest.cpp56
-rw-r--r--tests/querytest.cpp119
10 files changed, 234 insertions, 254 deletions
diff --git a/common/datastorequery.cpp b/common/datastorequery.cpp
index 0fc9234..3c4ae00 100644
--- a/common/datastorequery.cpp
+++ b/common/datastorequery.cpp
@@ -146,6 +146,7 @@ public:
146 typedef QSharedPointer<Reduce> Ptr; 146 typedef QSharedPointer<Reduce> Ptr;
147 147
148 QHash<QByteArray, QVariant> mAggregateValues; 148 QHash<QByteArray, QVariant> mAggregateValues;
149 QSet<QByteArray> mReducedValues;
149 QByteArray mReductionProperty; 150 QByteArray mReductionProperty;
150 QByteArray mSelectionProperty; 151 QByteArray mSelectionProperty;
151 Query::Reduce::Selector::Comparator mSelectionComparator; 152 Query::Reduce::Selector::Comparator mSelectionComparator;
@@ -184,7 +185,9 @@ public:
184 bool foundValue = false; 185 bool foundValue = false;
185 while(!foundValue && mSource->next([this, callback, &foundValue](Sink::Operation operation, const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) { 186 while(!foundValue && mSource->next([this, callback, &foundValue](Sink::Operation operation, const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) {
186 auto reductionValue = getProperty(entityBuffer.entity(), mReductionProperty); 187 auto reductionValue = getProperty(entityBuffer.entity(), mReductionProperty);
187 if (!mAggregateValues.contains(getByteArray(reductionValue))) { 188 if (!mReducedValues.contains(getByteArray(reductionValue))) {
189 //Only reduce every value once.
190 mReducedValues.insert(getByteArray(reductionValue));
188 QVariant selectionResultValue; 191 QVariant selectionResultValue;
189 QByteArray selectionResult; 192 QByteArray selectionResult;
190 auto results = indexLookup(mReductionProperty, reductionValue); 193 auto results = indexLookup(mReductionProperty, reductionValue);
@@ -373,17 +376,16 @@ QVector<QByteArray> DataStoreQuery::indexLookup(const QByteArray &property, cons
373void DataStoreQuery::setupQuery() 376void DataStoreQuery::setupQuery()
374{ 377{
375 FilterBase::Ptr baseSet; 378 FilterBase::Ptr baseSet;
376 QSet<QByteArray> remainingFilters; 379 QSet<QByteArray> remainingFilters = mQuery.getBaseFilters().keys().toSet();
377 QByteArray appliedSorting; 380 QByteArray appliedSorting;
378 if (!mQuery.ids.isEmpty()) { 381 if (!mQuery.ids.isEmpty()) {
379 mSource = Source::Ptr::create(mQuery.ids.toVector(), this); 382 mSource = Source::Ptr::create(mQuery.ids.toVector(), this);
380 baseSet = mSource; 383 baseSet = mSource;
381 remainingFilters = mQuery.propertyFilter.keys().toSet();
382 } else { 384 } else {
383 QSet<QByteArray> appliedFilters; 385 QSet<QByteArray> appliedFilters;
384 386
385 auto resultSet = mTypeIndex.query(mQuery, appliedFilters, appliedSorting, mTransaction); 387 auto resultSet = mTypeIndex.query(mQuery, appliedFilters, appliedSorting, mTransaction);
386 remainingFilters = mQuery.propertyFilter.keys().toSet() - appliedFilters; 388 remainingFilters = remainingFilters - appliedFilters;
387 389
388 // We do a full scan if there were no indexes available to create the initial set. 390 // We do a full scan if there were no indexes available to create the initial set.
389 if (appliedFilters.isEmpty()) { 391 if (appliedFilters.isEmpty()) {
@@ -394,12 +396,12 @@ void DataStoreQuery::setupQuery()
394 } 396 }
395 baseSet = mSource; 397 baseSet = mSource;
396 } 398 }
397 if (!mQuery.propertyFilter.isEmpty()) { 399 if (!mQuery.getBaseFilters().isEmpty()) {
398 auto filter = Filter::Ptr::create(baseSet, this); 400 auto filter = Filter::Ptr::create(baseSet, this);
399 filter->propertyFilter = mQuery.propertyFilter; 401 //For incremental queries the remaining filters are not sufficient
400 /* for (const auto &f : remainingFilters) { */ 402 for (const auto &f : mQuery.getBaseFilters().keys()) {
401 /* filter->propertyFilter.insert(f, mQuery.propertyFilter.value(f)); */ 403 filter->propertyFilter.insert(f, mQuery.getFilter(f));
402 /* } */ 404 }
403 baseSet = filter; 405 baseSet = filter;
404 } 406 }
405 /* if (appliedSorting.isEmpty() && !mQuery.sortProperty.isEmpty()) { */ 407 /* if (appliedSorting.isEmpty() && !mQuery.sortProperty.isEmpty()) { */
@@ -407,15 +409,16 @@ void DataStoreQuery::setupQuery()
407 /* baseSet = Sort::Ptr::create(baseSet, mQuery.sortProperty); */ 409 /* baseSet = Sort::Ptr::create(baseSet, mQuery.sortProperty); */
408 /* } */ 410 /* } */
409 411
412 //Setup the rest of the filter stages on top of the base set
410 for (const auto &stage : mQuery.filterStages) { 413 for (const auto &stage : mQuery.filterStages) {
411 if (auto filter = stage.dynamicCast<Query::Filter>()) { 414 if (auto filter = stage.dynamicCast<Query::Filter>()) {
412 415 auto f = Filter::Ptr::create(baseSet, this);
416 f->propertyFilter = filter->propertyFilter;
417 baseSet = f;
413 } else if (auto filter = stage.dynamicCast<Query::Reduce>()) { 418 } else if (auto filter = stage.dynamicCast<Query::Reduce>()) {
414 auto reduce = Reduce::Ptr::create(filter->property, filter->selector.property, filter->selector.comparator, baseSet, this); 419 baseSet = Reduce::Ptr::create(filter->property, filter->selector.property, filter->selector.comparator, baseSet, this);
415 baseSet = reduce;
416 } else if (auto filter = stage.dynamicCast<Query::Bloom>()) { 420 } else if (auto filter = stage.dynamicCast<Query::Bloom>()) {
417 auto reduce = Bloom::Ptr::create(filter->property, baseSet, this); 421 baseSet = Bloom::Ptr::create(filter->property, baseSet, this);
418 baseSet = reduce;
419 } 422 }
420 } 423 }
421 424
diff --git a/common/query.h b/common/query.h
index 0c6260b..3362ac7 100644
--- a/common/query.h
+++ b/common/query.h
@@ -58,26 +58,6 @@ public:
58 Comparators comparator; 58 Comparators comparator;
59 }; 59 };
60 60
61
62 static Query PropertyFilter(const QByteArray &key, const QVariant &value)
63 {
64 Query query;
65 query.propertyFilter.insert(key, Comparator(value));
66 return query;
67 }
68
69 static Query PropertyContainsFilter(const QByteArray &key, const QVariant &value)
70 {
71 Query query;
72 query.propertyFilter.insert(key, Comparator(value, Comparator::Contains));
73 return query;
74 }
75
76 static Query PropertyFilter(const QByteArray &key, const ApplicationDomain::Entity &entity)
77 {
78 return PropertyFilter(key, QVariant::fromValue(entity.identifier()));
79 }
80
81 static Query ResourceFilter(const QByteArray &identifier) 61 static Query ResourceFilter(const QByteArray &identifier)
82 { 62 {
83 Query query; 63 Query query;
@@ -97,33 +77,6 @@ public:
97 return ResourceFilter(entity.identifier()); 77 return ResourceFilter(entity.identifier());
98 } 78 }
99 79
100 static Query AccountFilter(const QByteArray &identifier)
101 {
102 Query query;
103 query.accounts.append(identifier);
104 return query;
105 }
106
107 static Query CapabilityFilter(const QByteArray &capability)
108 {
109 Query query;
110 query.propertyFilter.insert("capabilities", Comparator(capability, Comparator::Contains));
111 return query;
112 }
113
114 static Query AccountFilter(const QByteArrayList &identifier)
115 {
116 Q_ASSERT(!identifier.isEmpty());
117 Query query;
118 query.accounts = identifier;
119 return query;
120 }
121
122 static Query AccountFilter(const ApplicationDomain::SinkAccount &entity)
123 {
124 return AccountFilter(entity.identifier());
125 }
126
127 static Query IdentityFilter(const QByteArray &identifier) 80 static Query IdentityFilter(const QByteArray &identifier)
128 { 81 {
129 Q_ASSERT(!identifier.isEmpty()); 82 Q_ASSERT(!identifier.isEmpty());
@@ -146,24 +99,17 @@ public:
146 return query; 99 return query;
147 } 100 }
148 101
149 static Query RequestedProperties(const QByteArrayList &properties) 102 template <typename T>
150 { 103 Query &request()
151 Query query;
152 query.requestedProperties = properties;
153 return query;
154 }
155
156 static Query RequestTree(const QByteArray &parentProperty)
157 { 104 {
158 Query query; 105 requestedProperties << T::name;
159 query.parentProperty = parentProperty; 106 return *this;
160 return query;
161 } 107 }
162 108
163 template <typename T> 109 template <typename T>
164 Query &request() 110 Query &requestTree()
165 { 111 {
166 requestedProperties << T::name; 112 parentProperty = T::name;
167 return *this; 113 return *this;
168 } 114 }
169 115
@@ -227,9 +173,8 @@ public:
227 * Filters 173 * Filters
228 */ 174 */
229 class Filter : public FilterStage { 175 class Filter : public FilterStage {
230 QByteArrayList ids; 176 public:
231 QHash<QByteArray, Comparator> propertyFilter; 177 QHash<QByteArray, Comparator> propertyFilter;
232 QByteArray sortProperty;
233 }; 178 };
234 179
235 template <typename T> 180 template <typename T>
@@ -239,6 +184,12 @@ public:
239 } 184 }
240 185
241 template <typename T> 186 template <typename T>
187 Query &containsFilter(const QVariant &value)
188 {
189 return filter(T::name, Comparator(value, Comparator::Contains));
190 }
191
192 template <typename T>
242 Query &filter(const Comparator &comparator) 193 Query &filter(const Comparator &comparator)
243 { 194 {
244 return filter(T::name, comparator); 195 return filter(T::name, comparator);
@@ -362,6 +313,39 @@ public:
362 filterStages << bloom; 313 filterStages << bloom;
363 } 314 }
364 315
316 //Query fixtures
317
318 /**
319 * Returns the complete thread, containing all mails from all folders.
320 */
321 static Query completeThread(const ApplicationDomain::Mail &mail)
322 {
323 Sink::Query query;
324 if (!mail.resourceInstanceIdentifier().isEmpty()) {
325 query.filter(ApplicationDomain::SinkResource(mail.resourceInstanceIdentifier()));
326 }
327 query.ids << mail.identifier();
328 query.sort<ApplicationDomain::Mail::Date>();
329 query.bloom<ApplicationDomain::Mail::ThreadId>();
330 return query;
331 }
332
333 /**
334 * Returns thread leaders only, sorted by date.
335 */
336 static Query threadLeaders(const ApplicationDomain::Folder &folder)
337 {
338 Sink::Query query;
339 if (!folder.resourceInstanceIdentifier().isEmpty()) {
340 query.filter(ApplicationDomain::SinkResource(folder.resourceInstanceIdentifier()));
341 }
342 query.filter<ApplicationDomain::Mail::Folder>(folder);
343 query.sort<ApplicationDomain::Mail::Date>();
344 query.reduce<ApplicationDomain::Mail::ThreadId>(Query::Reduce::Selector::max<ApplicationDomain::Mail::Date>());
345 return query;
346 }
347
348
365}; 349};
366 350
367} 351}
diff --git a/common/test.cpp b/common/test.cpp
index 1a8e11d..97c42ef 100644
--- a/common/test.cpp
+++ b/common/test.cpp
@@ -147,7 +147,7 @@ public:
147 } 147 }
148 SinkTrace() << "-------------------------."; 148 SinkTrace() << "-------------------------.";
149 for (const auto &res : mTestAccount->entities<T>()) { 149 for (const auto &res : mTestAccount->entities<T>()) {
150 qDebug() << "Parent filter " << query.propertyFilter.value("parent").value.toByteArray() << res->identifier() << res->getProperty("parent").toByteArray(); 150 qDebug() << "Parent filter " << query.getFilter("parent").value.toByteArray() << res->identifier() << res->getProperty("parent").toByteArray();
151 auto parentProperty = res->getProperty("parent").toByteArray(); 151 auto parentProperty = res->getProperty("parent").toByteArray();
152 if ((!parent && parentProperty.isEmpty()) || (parent && parentProperty == parent->identifier()) || query.parentProperty.isEmpty()) { 152 if ((!parent && parentProperty.isEmpty()) || (parent && parentProperty == parent->identifier()) || query.parentProperty.isEmpty()) {
153 qDebug() << "Found a match" << res->identifier(); 153 qDebug() << "Found a match" << res->identifier();
diff --git a/sinksh/syntax_modules/sink_list.cpp b/sinksh/syntax_modules/sink_list.cpp
index b20f3d4..2d7ef5f 100644
--- a/sinksh/syntax_modules/sink_list.cpp
+++ b/sinksh/syntax_modules/sink_list.cpp
@@ -60,11 +60,11 @@ bool list(const QStringList &args, State &state)
60 if (filterIndex >= 0) { 60 if (filterIndex >= 0) {
61 for (int i = 1; i < filterIndex; i++) { 61 for (int i = 1; i < filterIndex; i++) {
62 query.resources << args.at(i).toLatin1(); 62 query.resources << args.at(i).toLatin1();
63 query += Sink::Query::ResourceFilter(args.at(i).toLatin1()); 63 query.filter(Sink::ApplicationDomain::SinkResource(args.at(i).toLatin1()));
64 } 64 }
65 for (int i = filterIndex + 1; i < args.size(); i++) { 65 for (int i = filterIndex + 1; i < args.size(); i++) {
66 auto filter = args.at(i).split("="); 66 auto filter = args.at(i).split("=");
67 query += Sink::Query::PropertyFilter(filter.at(0).toLatin1(), filter.at(1)); 67 query.filter(filter.at(0).toLatin1(), QVariant::fromValue(filter.at(1)));
68 } 68 }
69 69
70 } 70 }
diff --git a/tests/clientapitest.cpp b/tests/clientapitest.cpp
index b5405cf..44eb845 100644
--- a/tests/clientapitest.cpp
+++ b/tests/clientapitest.cpp
@@ -61,7 +61,7 @@ public:
61 } 61 }
62 SinkTrace() << "-------------------------."; 62 SinkTrace() << "-------------------------.";
63 for (const auto &res : results) { 63 for (const auto &res : results) {
64 qDebug() << "Parent filter " << query.propertyFilter.value("parent").value.toByteArray() << res->identifier() << res->getProperty("parent").toByteArray(); 64 qDebug() << "Parent filter " << query.getFilter("parent").value.toByteArray() << res->identifier() << res->getProperty("parent").toByteArray();
65 auto parentProperty = res->getProperty("parent").toByteArray(); 65 auto parentProperty = res->getProperty("parent").toByteArray();
66 if ((!parent && parentProperty.isEmpty()) || (parent && parentProperty == parent->identifier()) || query.parentProperty.isEmpty()) { 66 if ((!parent && parentProperty.isEmpty()) || (parent && parentProperty == parent->identifier()) || query.parentProperty.isEmpty()) {
67 qDebug() << "Found a hit" << res->identifier(); 67 qDebug() << "Found a hit" << res->identifier();
diff --git a/tests/dummyresourcetest.cpp b/tests/dummyresourcetest.cpp
index 687a33b..a7a492c 100644
--- a/tests/dummyresourcetest.cpp
+++ b/tests/dummyresourcetest.cpp
@@ -14,6 +14,7 @@
14#include "test.h" 14#include "test.h"
15 15
16using namespace Sink; 16using namespace Sink;
17using namespace Sink::ApplicationDomain;
17 18
18/** 19/**
19 * Test of complete system using the dummy resource. 20 * Test of complete system using the dummy resource.
@@ -32,7 +33,7 @@ private slots:
32 Sink::Test::initTest(); 33 Sink::Test::initTest();
33 auto factory = Sink::ResourceFactory::load("sink.dummy"); 34 auto factory = Sink::ResourceFactory::load("sink.dummy");
34 QVERIFY(factory); 35 QVERIFY(factory);
35 DummyResource::removeFromDisk("sink.dummy.instance1"); 36 ::DummyResource::removeFromDisk("sink.dummy.instance1");
36 ResourceConfig::addResource("sink.dummy.instance1", "sink.dummy"); 37 ResourceConfig::addResource("sink.dummy.instance1", "sink.dummy");
37 } 38 }
38 39
@@ -52,49 +53,49 @@ private slots:
52 53
53 void testProperty() 54 void testProperty()
54 { 55 {
55 Sink::ApplicationDomain::Event event; 56 Event event;
56 event.setProperty("uid", "testuid"); 57 event.setProperty("uid", "testuid");
57 QCOMPARE(event.getProperty("uid").toByteArray(), QByteArray("testuid")); 58 QCOMPARE(event.getProperty("uid").toByteArray(), QByteArray("testuid"));
58 } 59 }
59 60
60 void testWriteToFacadeAndQueryByUid() 61 void testWriteToFacadeAndQueryByUid()
61 { 62 {
62 Sink::ApplicationDomain::Event event("sink.dummy.instance1"); 63 Event event("sink.dummy.instance1");
63 event.setProperty("uid", "testuid"); 64 event.setProperty("uid", "testuid");
64 QCOMPARE(event.getProperty("uid").toByteArray(), QByteArray("testuid")); 65 QCOMPARE(event.getProperty("uid").toByteArray(), QByteArray("testuid"));
65 event.setProperty("summary", "summaryValue"); 66 event.setProperty("summary", "summaryValue");
66 Sink::Store::create<Sink::ApplicationDomain::Event>(event).exec().waitForFinished(); 67 Sink::Store::create<Event>(event).exec().waitForFinished();
67 68
68 const auto query = Query::ResourceFilter("sink.dummy.instance1") ; 69 auto query = Query::ResourceFilter("sink.dummy.instance1") ;
69 70
70 // Ensure all local data is processed 71 // Ensure all local data is processed
71 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 72 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
72 73
73 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query + Query::PropertyFilter("uid", "testuid")); 74 auto model = Sink::Store::loadModel<Event>(query.filter<Event::Uid>("testuid"));
74 QTRY_COMPARE(model->rowCount(QModelIndex()), 1); 75 QTRY_COMPARE(model->rowCount(QModelIndex()), 1);
75 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Event::Ptr>(); 76 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Event::Ptr>();
76 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid")); 77 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid"));
77 } 78 }
78 79
79 void testWriteToFacadeAndQueryByUid2() 80 void testWriteToFacadeAndQueryByUid2()
80 { 81 {
81 Sink::ApplicationDomain::Event event("sink.dummy.instance1"); 82 Event event("sink.dummy.instance1");
82 event.setProperty("summary", "summaryValue"); 83 event.setProperty("summary", "summaryValue");
83 84
84 event.setProperty("uid", "testuid"); 85 event.setProperty("uid", "testuid");
85 Sink::Store::create<Sink::ApplicationDomain::Event>(event).exec().waitForFinished(); 86 Sink::Store::create<Event>(event).exec().waitForFinished();
86 87
87 event.setProperty("uid", "testuid2"); 88 event.setProperty("uid", "testuid2");
88 Sink::Store::create<Sink::ApplicationDomain::Event>(event).exec().waitForFinished(); 89 Sink::Store::create<Event>(event).exec().waitForFinished();
89 90
90 const auto query = Query::ResourceFilter("sink.dummy.instance1") ; 91 auto query = Query::ResourceFilter("sink.dummy.instance1") ;
91 92
92 // Ensure all local data is processed 93 // Ensure all local data is processed
93 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 94 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
94 95
95 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query + Query::PropertyFilter("uid", "testuid")); 96 auto model = Sink::Store::loadModel<Event>(query.filter<Event::Uid>("testuid"));
96 QTRY_COMPARE(model->rowCount(QModelIndex()), 1); 97 QTRY_COMPARE(model->rowCount(QModelIndex()), 1);
97 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Event::Ptr>(); 98 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Event::Ptr>();
98 99
99 qDebug() << value->getProperty("uid").toByteArray(); 100 qDebug() << value->getProperty("uid").toByteArray();
100 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid")); 101 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid"));
@@ -102,24 +103,24 @@ private slots:
102 103
103 void testWriteToFacadeAndQueryBySummary() 104 void testWriteToFacadeAndQueryBySummary()
104 { 105 {
105 Sink::ApplicationDomain::Event event("sink.dummy.instance1"); 106 Event event("sink.dummy.instance1");
106 107
107 event.setProperty("uid", "testuid"); 108 event.setProperty("uid", "testuid");
108 event.setProperty("summary", "summaryValue1"); 109 event.setProperty("summary", "summaryValue1");
109 Sink::Store::create<Sink::ApplicationDomain::Event>(event).exec().waitForFinished(); 110 Sink::Store::create<Event>(event).exec().waitForFinished();
110 111
111 event.setProperty("uid", "testuid2"); 112 event.setProperty("uid", "testuid2");
112 event.setProperty("summary", "summaryValue2"); 113 event.setProperty("summary", "summaryValue2");
113 Sink::Store::create<Sink::ApplicationDomain::Event>(event).exec().waitForFinished(); 114 Sink::Store::create<Event>(event).exec().waitForFinished();
114 115
115 const auto query = Query::ResourceFilter("sink.dummy.instance1") ; 116 auto query = Query::ResourceFilter("sink.dummy.instance1") ;
116 117
117 // Ensure all local data is processed 118 // Ensure all local data is processed
118 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 119 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
119 120
120 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query + Query::PropertyFilter("summary", "summaryValue2")); 121 auto model = Sink::Store::loadModel<Event>(query.filter<Event::Summary>("summaryValue2"));
121 QTRY_COMPARE(model->rowCount(QModelIndex()), 1); 122 QTRY_COMPARE(model->rowCount(QModelIndex()), 1);
122 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Event::Ptr>(); 123 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Event::Ptr>();
123 124
124 qDebug() << value->getProperty("uid").toByteArray(); 125 qDebug() << value->getProperty("uid").toByteArray();
125 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid2")); 126 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid2"));
@@ -128,7 +129,7 @@ private slots:
128 void testResourceSync() 129 void testResourceSync()
129 { 130 {
130 auto pipeline = QSharedPointer<Sink::Pipeline>::create("sink.dummy.instance1"); 131 auto pipeline = QSharedPointer<Sink::Pipeline>::create("sink.dummy.instance1");
131 DummyResource resource("sink.dummy.instance1", pipeline); 132 ::DummyResource resource("sink.dummy.instance1", pipeline);
132 auto job = resource.synchronizeWithSource(); 133 auto job = resource.synchronizeWithSource();
133 // TODO pass in optional timeout? 134 // TODO pass in optional timeout?
134 auto future = job.exec(); 135 auto future = job.exec();
@@ -148,9 +149,9 @@ private slots:
148 Sink::Store::synchronize(query).exec().waitForFinished(); 149 Sink::Store::synchronize(query).exec().waitForFinished();
149 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 150 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
150 151
151 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query); 152 auto model = Sink::Store::loadModel<Event>(query);
152 QTRY_VERIFY(model->rowCount(QModelIndex()) >= 1); 153 QTRY_VERIFY(model->rowCount(QModelIndex()) >= 1);
153 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Event::Ptr>(); 154 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Event::Ptr>();
154 155
155 QVERIFY(!value->getProperty("summary").toString().isEmpty()); 156 QVERIFY(!value->getProperty("summary").toString().isEmpty());
156 qDebug() << value->getProperty("summary").toString(); 157 qDebug() << value->getProperty("summary").toString();
@@ -158,39 +159,40 @@ private slots:
158 159
159 void testSyncAndFacadeMail() 160 void testSyncAndFacadeMail()
160 { 161 {
161 const auto query = Query::ResourceFilter("sink.dummy.instance1"); 162 auto query = Query::ResourceFilter("sink.dummy.instance1");
163 query.request<Mail::Subject>();
162 164
163 // Ensure all local data is processed 165 // Ensure all local data is processed
164 Sink::Store::synchronize(query).exec().waitForFinished(); 166 Sink::Store::synchronize(query).exec().waitForFinished();
165 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 167 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
166 168
167 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Mail>(query); 169 auto model = Sink::Store::loadModel<Mail>(query);
168 QTRY_VERIFY(model->rowCount(QModelIndex()) >= 1); 170 QTRY_VERIFY(model->rowCount(QModelIndex()) >= 1);
169 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Mail::Ptr>(); 171 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Mail::Ptr>();
170 172
171 QVERIFY(!value->getProperty("subject").toString().isEmpty()); 173 qWarning() << value->getSubject() << value->identifier();
172 qDebug() << value->getProperty("subject").toString(); 174 QVERIFY(!value->getSubject().isEmpty());
173 } 175 }
174 176
175 void testWriteModifyDelete() 177 void testWriteModifyDelete()
176 { 178 {
177 Sink::ApplicationDomain::Event event("sink.dummy.instance1"); 179 Event event("sink.dummy.instance1");
178 event.setProperty("uid", "testuid"); 180 event.setProperty("uid", "testuid");
179 QCOMPARE(event.getProperty("uid").toByteArray(), QByteArray("testuid")); 181 QCOMPARE(event.getProperty("uid").toByteArray(), QByteArray("testuid"));
180 event.setProperty("summary", "summaryValue"); 182 event.setProperty("summary", "summaryValue");
181 Sink::Store::create<Sink::ApplicationDomain::Event>(event).exec().waitForFinished(); 183 Sink::Store::create<Event>(event).exec().waitForFinished();
182 184
183 const auto query = Query::ResourceFilter("sink.dummy.instance1") + Query::PropertyFilter("uid", "testuid"); 185 auto query = Query::ResourceFilter("sink.dummy.instance1").filter<Event::Uid>("testuid");
184 186
185 // Ensure all local data is processed 187 // Ensure all local data is processed
186 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 188 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
187 189
188 // Test create 190 // Test create
189 Sink::ApplicationDomain::Event event2; 191 Event event2;
190 { 192 {
191 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query); 193 auto model = Sink::Store::loadModel<Event>(query);
192 QTRY_COMPARE(model->rowCount(QModelIndex()), 1); 194 QTRY_COMPARE(model->rowCount(QModelIndex()), 1);
193 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Event::Ptr>(); 195 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Event::Ptr>();
194 196
195 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid")); 197 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid"));
196 QCOMPARE(value->getProperty("summary").toByteArray(), QByteArray("summaryValue")); 198 QCOMPARE(value->getProperty("summary").toByteArray(), QByteArray("summaryValue"));
@@ -199,29 +201,29 @@ private slots:
199 201
200 event2.setProperty("uid", "testuid"); 202 event2.setProperty("uid", "testuid");
201 event2.setProperty("summary", "summaryValue2"); 203 event2.setProperty("summary", "summaryValue2");
202 Sink::Store::modify<Sink::ApplicationDomain::Event>(event2).exec().waitForFinished(); 204 Sink::Store::modify<Event>(event2).exec().waitForFinished();
203 205
204 // Ensure all local data is processed 206 // Ensure all local data is processed
205 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 207 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
206 208
207 // Test modify 209 // Test modify
208 { 210 {
209 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query); 211 auto model = Sink::Store::loadModel<Event>(query);
210 QTRY_COMPARE(model->rowCount(QModelIndex()), 1); 212 QTRY_COMPARE(model->rowCount(QModelIndex()), 1);
211 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Event::Ptr>(); 213 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Event::Ptr>();
212 214
213 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid")); 215 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid"));
214 QCOMPARE(value->getProperty("summary").toByteArray(), QByteArray("summaryValue2")); 216 QCOMPARE(value->getProperty("summary").toByteArray(), QByteArray("summaryValue2"));
215 } 217 }
216 218
217 Sink::Store::remove<Sink::ApplicationDomain::Event>(event2).exec().waitForFinished(); 219 Sink::Store::remove<Event>(event2).exec().waitForFinished();
218 220
219 // Ensure all local data is processed 221 // Ensure all local data is processed
220 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 222 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
221 223
222 // Test remove 224 // Test remove
223 { 225 {
224 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query); 226 auto model = Sink::Store::loadModel<Event>(query);
225 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 227 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
226 QTRY_COMPARE(model->rowCount(QModelIndex()), 0); 228 QTRY_COMPARE(model->rowCount(QModelIndex()), 0);
227 } 229 }
@@ -231,22 +233,22 @@ private slots:
231 { 233 {
232 auto query = Query::ResourceFilter("sink.dummy.instance1"); 234 auto query = Query::ResourceFilter("sink.dummy.instance1");
233 query.liveQuery = true; 235 query.liveQuery = true;
234 query += Query::PropertyFilter("uid", "testuid"); 236 query.filter<Event::Uid>("testuid");
235 237
236 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Event>(query); 238 auto model = Sink::Store::loadModel<Event>(query);
237 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 239 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
238 240
239 Sink::ApplicationDomain::Event event("sink.dummy.instance1"); 241 Event event("sink.dummy.instance1");
240 event.setProperty("uid", "testuid"); 242 event.setProperty("uid", "testuid");
241 QCOMPARE(event.getProperty("uid").toByteArray(), QByteArray("testuid")); 243 QCOMPARE(event.getProperty("uid").toByteArray(), QByteArray("testuid"));
242 event.setProperty("summary", "summaryValue"); 244 event.setProperty("summary", "summaryValue");
243 Sink::Store::create<Sink::ApplicationDomain::Event>(event).exec().waitForFinished(); 245 Sink::Store::create<Event>(event).exec().waitForFinished();
244 246
245 // Test create 247 // Test create
246 Sink::ApplicationDomain::Event event2; 248 Event event2;
247 { 249 {
248 QTRY_COMPARE(model->rowCount(QModelIndex()), 1); 250 QTRY_COMPARE(model->rowCount(QModelIndex()), 1);
249 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Event::Ptr>(); 251 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Event::Ptr>();
250 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid")); 252 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid"));
251 QCOMPARE(value->getProperty("summary").toByteArray(), QByteArray("summaryValue")); 253 QCOMPARE(value->getProperty("summary").toByteArray(), QByteArray("summaryValue"));
252 event2 = *value; 254 event2 = *value;
@@ -254,18 +256,18 @@ private slots:
254 256
255 event2.setProperty("uid", "testuid"); 257 event2.setProperty("uid", "testuid");
256 event2.setProperty("summary", "summaryValue2"); 258 event2.setProperty("summary", "summaryValue2");
257 Sink::Store::modify<Sink::ApplicationDomain::Event>(event2).exec().waitForFinished(); 259 Sink::Store::modify<Event>(event2).exec().waitForFinished();
258 260
259 // Test modify 261 // Test modify
260 { 262 {
261 // TODO wait for a change signal 263 // TODO wait for a change signal
262 QTRY_COMPARE(model->rowCount(QModelIndex()), 1); 264 QTRY_COMPARE(model->rowCount(QModelIndex()), 1);
263 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Event::Ptr>(); 265 auto value = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Event::Ptr>();
264 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid")); 266 QCOMPARE(value->getProperty("uid").toByteArray(), QByteArray("testuid"));
265 QCOMPARE(value->getProperty("summary").toByteArray(), QByteArray("summaryValue2")); 267 QCOMPARE(value->getProperty("summary").toByteArray(), QByteArray("summaryValue2"));
266 } 268 }
267 269
268 Sink::Store::remove<Sink::ApplicationDomain::Event>(event2).exec().waitForFinished(); 270 Sink::Store::remove<Event>(event2).exec().waitForFinished();
269 271
270 // Test remove 272 // Test remove
271 { 273 {
diff --git a/tests/mailquerybenchmark.cpp b/tests/mailquerybenchmark.cpp
index 450955f..1d96819 100644
--- a/tests/mailquerybenchmark.cpp
+++ b/tests/mailquerybenchmark.cpp
@@ -45,6 +45,9 @@
45#include "createentity_generated.h" 45#include "createentity_generated.h"
46#include "getrssusage.h" 46#include "getrssusage.h"
47 47
48using namespace Sink;
49using namespace Sink::ApplicationDomain;
50
48/** 51/**
49 * Benchmark mail query performance. 52 * Benchmark mail query performance.
50 */ 53 */
@@ -62,7 +65,7 @@ class MailQueryBenchmark : public QObject
62 auto pipeline = QSharedPointer<Sink::Pipeline>::create(resourceIdentifier); 65 auto pipeline = QSharedPointer<Sink::Pipeline>::create(resourceIdentifier);
63 pipeline->setResourceType("test"); 66 pipeline->setResourceType("test");
64 67
65 auto indexer = QSharedPointer<DefaultIndexUpdater<Sink::ApplicationDomain::Mail>>::create(); 68 auto indexer = QSharedPointer<DefaultIndexUpdater<Mail>>::create();
66 69
67 pipeline->setPreprocessors("mail", QVector<Sink::Preprocessor *>() << indexer.data()); 70 pipeline->setPreprocessors("mail", QVector<Sink::Preprocessor *>() << indexer.data());
68 71
@@ -71,13 +74,13 @@ class MailQueryBenchmark : public QObject
71 pipeline->startTransaction(); 74 pipeline->startTransaction();
72 const auto date = QDateTime::currentDateTimeUtc(); 75 const auto date = QDateTime::currentDateTimeUtc();
73 for (int i = 0; i < count; i++) { 76 for (int i = 0; i < count; i++) {
74 auto domainObject = Sink::ApplicationDomain::Mail::Ptr::create(); 77 auto domainObject = Mail::Ptr::create();
75 domainObject->setProperty("uid", "uid"); 78 domainObject->setProperty("uid", "uid");
76 domainObject->setProperty("subject", QString("subject%1").arg(i)); 79 domainObject->setProperty("subject", QString("subject%1").arg(i));
77 domainObject->setProperty("date", date.addSecs(count)); 80 domainObject->setProperty("date", date.addSecs(count));
78 domainObject->setProperty("folder", "folder1"); 81 domainObject->setProperty("folder", "folder1");
79 // domainObject->setProperty("attachment", attachment); 82 // domainObject->setProperty("attachment", attachment);
80 const auto command = createCommand<Sink::ApplicationDomain::Mail>(*domainObject, *domainTypeAdaptorFactory); 83 const auto command = createCommand<Mail>(*domainObject, *domainTypeAdaptorFactory);
81 pipeline->newEntity(command.data(), command.size()); 84 pipeline->newEntity(command.data(), command.size());
82 } 85 }
83 pipeline->commit(); 86 pipeline->commit();
@@ -92,18 +95,18 @@ class MailQueryBenchmark : public QObject
92 QTime time; 95 QTime time;
93 time.start(); 96 time.start();
94 97
95 auto resultSet = QSharedPointer<Sink::ResultProvider<Sink::ApplicationDomain::Mail::Ptr>>::create(); 98 auto resultSet = QSharedPointer<Sink::ResultProvider<Mail::Ptr>>::create();
96 auto resourceAccess = QSharedPointer<TestResourceAccess>::create(); 99 auto resourceAccess = QSharedPointer<TestResourceAccess>::create();
97 TestMailResourceFacade facade(resourceIdentifier, resourceAccess); 100 TestMailResourceFacade facade(resourceIdentifier, resourceAccess);
98 101
99 auto ret = facade.load(query); 102 auto ret = facade.load(query);
100 ret.first.exec().waitForFinished(); 103 ret.first.exec().waitForFinished();
101 auto emitter = ret.second; 104 auto emitter = ret.second;
102 QList<Sink::ApplicationDomain::Mail::Ptr> list; 105 QList<Mail::Ptr> list;
103 emitter->onAdded([&list](const Sink::ApplicationDomain::Mail::Ptr &mail) { list << mail; }); 106 emitter->onAdded([&list](const Mail::Ptr &mail) { list << mail; });
104 bool done = false; 107 bool done = false;
105 emitter->onInitialResultSetComplete([&done](const Sink::ApplicationDomain::Mail::Ptr &mail) { done = true; }); 108 emitter->onInitialResultSetComplete([&done](const Mail::Ptr &mail) { done = true; });
106 emitter->fetch(Sink::ApplicationDomain::Mail::Ptr()); 109 emitter->fetch(Mail::Ptr());
107 QTRY_VERIFY(done); 110 QTRY_VERIFY(done);
108 QCOMPARE(list.size(), query.limit); 111 QCOMPARE(list.size(), query.limit);
109 112
@@ -149,18 +152,18 @@ private slots:
149 void init() 152 void init()
150 { 153 {
151 resourceIdentifier = "sink.test.instance1"; 154 resourceIdentifier = "sink.test.instance1";
152 Sink::AdaptorFactoryRegistry::instance().registerFactory<Sink::ApplicationDomain::Mail, TestMailAdaptorFactory>("test"); 155 Sink::AdaptorFactoryRegistry::instance().registerFactory<Mail, TestMailAdaptorFactory>("test");
153 } 156 }
154 157
155 void test50k() 158 void test50k()
156 { 159 {
157 Sink::Query query; 160 Sink::Query query;
158 query.liveQuery = false; 161 query.liveQuery = false;
159 query.requestedProperties << "uid" 162 query.request<Mail::Uid>()
160 << "subject" 163 .request<Mail::Subject>()
161 << "date"; 164 .request<Mail::Date>();
162 query.sortProperty = "date"; 165 query.sort<Mail::Date>();
163 query += Sink::Query::PropertyFilter("folder", "folder1"); 166 query.filter<Mail::Folder>("folder1");
164 query.limit = 1000; 167 query.limit = 1000;
165 168
166 populateDatabase(50000); 169 populateDatabase(50000);
diff --git a/tests/mailtest.cpp b/tests/mailtest.cpp
index 925fb70..ed145d4 100644
--- a/tests/mailtest.cpp
+++ b/tests/mailtest.cpp
@@ -39,12 +39,13 @@ void MailTest::initTestCase()
39 QVERIFY(isBackendAvailable()); 39 QVERIFY(isBackendAvailable());
40 resetTestEnvironment(); 40 resetTestEnvironment();
41 auto resource = createResource(); 41 auto resource = createResource();
42 QVERIFY(!resource.getResourceType().isEmpty());
42 QVERIFY(!resource.identifier().isEmpty()); 43 QVERIFY(!resource.identifier().isEmpty());
43 44
44 VERIFYEXEC(Store::create(resource)); 45 VERIFYEXEC(Store::create(resource));
45 46
46 mResourceInstanceIdentifier = resource.identifier(); 47 mResourceInstanceIdentifier = resource.identifier();
47 mCapabilities = resource.getProperty("capabilities").value<QByteArrayList>(); 48 mCapabilities = resource.getCapabilities();
48} 49}
49 50
50void MailTest::cleanup() 51void MailTest::cleanup()
@@ -82,7 +83,7 @@ void MailTest::testCreateModifyDeleteFolder()
82 VERIFYEXEC(Store::create(folder)); 83 VERIFYEXEC(Store::create(folder));
83 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); 84 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier));
84 { 85 {
85 auto job = Store::fetchAll<Folder>(Query::RequestedProperties(QByteArrayList() << Folder::Name::name << Folder::Icon::name)) 86 auto job = Store::fetchAll<Folder>(Query().request<Folder::Name>().request<Folder::Icon>())
86 .syncThen<void, QList<Folder::Ptr>>([=](const QList<Folder::Ptr> &folders) { 87 .syncThen<void, QList<Folder::Ptr>>([=](const QList<Folder::Ptr> &folders) {
87 QCOMPARE(folders.size(), baseCount + 1); 88 QCOMPARE(folders.size(), baseCount + 1);
88 QHash<QString, Folder::Ptr> foldersByName; 89 QHash<QString, Folder::Ptr> foldersByName;
@@ -108,7 +109,7 @@ void MailTest::testCreateModifyDeleteFolder()
108 VERIFYEXEC(Store::modify(folder)); 109 VERIFYEXEC(Store::modify(folder));
109 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); 110 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier));
110 { 111 {
111 auto job = Store::fetchAll<Folder>(Query::RequestedProperties(QByteArrayList() << Folder::Name::name << Folder::Icon::name)) 112 auto job = Store::fetchAll<Folder>(Query().request<Folder::Name>().request<Folder::Icon>())
112 .syncThen<void, QList<Folder::Ptr>>([=](const QList<Folder::Ptr> &folders) { 113 .syncThen<void, QList<Folder::Ptr>>([=](const QList<Folder::Ptr> &folders) {
113 QCOMPARE(folders.size(), baseCount + 1); 114 QCOMPARE(folders.size(), baseCount + 1);
114 QHash<QString, Folder::Ptr> foldersByName; 115 QHash<QString, Folder::Ptr> foldersByName;
@@ -129,7 +130,7 @@ void MailTest::testCreateModifyDeleteFolder()
129 VERIFYEXEC(Store::remove(folder)); 130 VERIFYEXEC(Store::remove(folder));
130 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); 131 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier));
131 { 132 {
132 auto job = Store::fetchAll<Folder>(Query::RequestedProperties(QByteArrayList() << Folder::Name::name << Folder::Icon::name)) 133 auto job = Store::fetchAll<Folder>(Query().request<Folder::Name>().request<Folder::Icon>())
133 .syncThen<void, QList<Folder::Ptr>>([=](const QList<Folder::Ptr> &folders) { 134 .syncThen<void, QList<Folder::Ptr>>([=](const QList<Folder::Ptr> &folders) {
134 QCOMPARE(folders.size(), baseCount); 135 QCOMPARE(folders.size(), baseCount);
135 }); 136 });
@@ -159,7 +160,7 @@ void MailTest::testCreateModifyDeleteMail()
159 VERIFYEXEC(Store::create(mail)); 160 VERIFYEXEC(Store::create(mail));
160 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); 161 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier));
161 { 162 {
162 auto job = Store::fetchAll<Mail>(Query::RequestedProperties(QByteArrayList() << Mail::Folder::name << Mail::Subject::name << Mail::MimeMessage::name)) 163 auto job = Store::fetchAll<Mail>(Query().request<Mail::Folder>().request<Mail::Subject>().request<Mail::MimeMessage>())
163 .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { 164 .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) {
164 QCOMPARE(mails.size(), 1); 165 QCOMPARE(mails.size(), 1);
165 auto mail = *mails.first(); 166 auto mail = *mails.first();
@@ -188,7 +189,7 @@ void MailTest::testCreateModifyDeleteMail()
188 VERIFYEXEC(Store::modify(mail)); 189 VERIFYEXEC(Store::modify(mail));
189 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); 190 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier));
190 { 191 {
191 auto job = Store::fetchAll<Mail>(Query::RequestedProperties(QByteArrayList() << Mail::Folder::name << Mail::Subject::name << Mail::MimeMessage::name)) 192 auto job = Store::fetchAll<Mail>(Query().request<Mail::Folder>().request<Mail::Subject>().request<Mail::MimeMessage>())
192 .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { 193 .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) {
193 QCOMPARE(mails.size(), 1); 194 QCOMPARE(mails.size(), 1);
194 auto mail = *mails.first(); 195 auto mail = *mails.first();
@@ -210,7 +211,7 @@ void MailTest::testCreateModifyDeleteMail()
210 VERIFYEXEC(Store::remove(mail)); 211 VERIFYEXEC(Store::remove(mail));
211 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); 212 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier));
212 { 213 {
213 auto job = Store::fetchAll<Mail>(Query::RequestedProperties(QByteArrayList() << Mail::Folder::name << Mail::Subject::name)) 214 auto job = Store::fetchAll<Mail>(Query().request<Mail::Folder>().request<Mail::Subject>())
214 .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { 215 .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) {
215 QCOMPARE(mails.size(), 0); 216 QCOMPARE(mails.size(), 0);
216 }); 217 });
@@ -246,7 +247,7 @@ void MailTest::testMoveMail()
246 247
247 Mail modifiedMail; 248 Mail modifiedMail;
248 { 249 {
249 auto job = Store::fetchAll<Mail>(Query::RequestedProperties(QByteArrayList() << Mail::Folder::name << Mail::Subject::name << Mail::MimeMessage::name)) 250 auto job = Store::fetchAll<Mail>(Query().request<Mail::Folder>().request<Mail::Subject>().request<Mail::MimeMessage>())
250 .syncThen<void, QList<Mail::Ptr>>([=, &modifiedMail](const QList<Mail::Ptr> &mails) { 251 .syncThen<void, QList<Mail::Ptr>>([=, &modifiedMail](const QList<Mail::Ptr> &mails) {
251 QCOMPARE(mails.size(), 1); 252 QCOMPARE(mails.size(), 1);
252 auto mail = *mails.first(); 253 auto mail = *mails.first();
@@ -265,7 +266,7 @@ void MailTest::testMoveMail()
265 VERIFYEXEC(Store::modify(modifiedMail)); 266 VERIFYEXEC(Store::modify(modifiedMail));
266 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); 267 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier));
267 { 268 {
268 auto job = Store::fetchAll<Mail>(Query::RequestedProperties(QByteArrayList() << Mail::Folder::name << Mail::Subject::name << Mail::MimeMessage::name)) 269 auto job = Store::fetchAll<Mail>(Query().request<Mail::Folder>().request<Mail::Subject>().request<Mail::MimeMessage>())
269 .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { 270 .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) {
270 QCOMPARE(mails.size(), 1); 271 QCOMPARE(mails.size(), 1);
271 auto mail = *mails.first(); 272 auto mail = *mails.first();
@@ -296,9 +297,11 @@ void MailTest::testMarkMailAsRead()
296 VERIFYEXEC(Store::create(mail)); 297 VERIFYEXEC(Store::create(mail));
297 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); 298 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier));
298 299
299 auto job = Store::fetchAll<Mail>(Query::ResourceFilter(mResourceInstanceIdentifier) + 300 auto job = Store::fetchAll<Mail>(Query()
300 Query::RequestedProperties(QByteArrayList() << Mail::Folder::name 301 .filter(SinkResource(mResourceInstanceIdentifier))
301 << Mail::Subject::name)) 302 .request<Mail::Folder>()
303 .request<Mail::Subject>()
304 )
302 .then<void, QList<Mail::Ptr>>([this](const QList<Mail::Ptr> &mails) { 305 .then<void, QList<Mail::Ptr>>([this](const QList<Mail::Ptr> &mails) {
303 ASYNCCOMPARE(mails.size(), 1); 306 ASYNCCOMPARE(mails.size(), 1);
304 auto mail = mails.first(); 307 auto mail = mails.first();
@@ -311,11 +314,13 @@ void MailTest::testMarkMailAsRead()
311 VERIFYEXEC(job); 314 VERIFYEXEC(job);
312 315
313 // Verify that we can still query for all relevant information 316 // Verify that we can still query for all relevant information
314 auto job2 = Store::fetchAll<Mail>( 317 auto job2 = Store::fetchAll<Mail>(Query()
315 Query::ResourceFilter(mResourceInstanceIdentifier) + Query::RequestedProperties(QByteArrayList() << Mail::Folder::name 318 .filter(SinkResource(mResourceInstanceIdentifier))
316 << Mail::Subject::name 319 .request<Mail::Folder>()
317 << Mail::MimeMessage::name 320 .request<Mail::Subject>()
318 << Mail::Unread::name)) 321 .request<Mail::MimeMessage>()
322 .request<Mail::Unread>()
323 )
319 .then<void, QList<Mail::Ptr>>([](const QList<Mail::Ptr> &mails) { 324 .then<void, QList<Mail::Ptr>>([](const QList<Mail::Ptr> &mails) {
320 ASYNCCOMPARE(mails.size(), 1); 325 ASYNCCOMPARE(mails.size(), 1);
321 auto mail = mails.first(); 326 auto mail = mails.first();
diff --git a/tests/mailthreadtest.cpp b/tests/mailthreadtest.cpp
index e9fe499..6ba54df 100644
--- a/tests/mailthreadtest.cpp
+++ b/tests/mailthreadtest.cpp
@@ -75,11 +75,9 @@ void MailThreadTest::testListThreadLeader()
75 VERIFYEXEC(Store::synchronize(query)); 75 VERIFYEXEC(Store::synchronize(query));
76 ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 76 ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
77 77
78 auto job = Store::fetchAll<Mail>(query).syncThen<void, QList<Mail::Ptr>>([](const QList<Mail::Ptr> &mails) { 78 auto mails = Store::read<Mail>(query);
79 QCOMPARE(mails.size(), 1); 79 QCOMPARE(mails.size(), 1);
80 QVERIFY(mails.first()->getSubject().startsWith(QString("ThreadLeader"))); 80 QVERIFY(mails.first().getSubject().startsWith(QString("ThreadLeader")));
81 });
82 VERIFYEXEC(job);
83} 81}
84 82
85/* 83/*
@@ -126,25 +124,19 @@ void MailThreadTest::testIndexInMixedOrder()
126 } 124 }
127 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); 125 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier));
128 126
129 Sink::Query query; 127 auto query = Sink::Query::threadLeaders(folder);
130 query.filter(SinkResource(mResourceInstanceIdentifier)); 128 query.filter(SinkResource(mResourceInstanceIdentifier));
131 query.request<Mail::Subject>().request<Mail::MimeMessage>().request<Mail::Folder>().request<Mail::Date>(); 129 query.request<Mail::Subject>().request<Mail::MimeMessage>().request<Mail::Folder>().request<Mail::Date>();
132 query.filter<Mail::Folder>(folder);
133 query.sort<Mail::Date>();
134 query.reduce<Mail::ThreadId>(Query::Reduce::Selector::max<Mail::Date>());
135 130
136 Mail threadLeader; 131 Mail threadLeader;
137 132
138 //Ensure we find the thread leader 133 //Ensure we find the thread leader
139 { 134 {
140 auto job = Store::fetchAll<Mail>(query) 135 auto mails = Store::read<Mail>(query);
141 .syncThen<void, QList<Mail::Ptr>>([=, &threadLeader](const QList<Mail::Ptr> &mails) { 136 QCOMPARE(mails.size(), 1);
142 QCOMPARE(mails.size(), 1); 137 auto mail = mails.first();
143 auto mail = *mails.first(); 138 threadLeader = mail;
144 threadLeader = mail; 139 QCOMPARE(mail.getSubject(), QString::fromLatin1("Re: Re: 1"));
145 QCOMPARE(mail.getSubject(), QString::fromLatin1("Re: Re: 1"));
146 });
147 VERIFYEXEC(job);
148 } 140 }
149 141
150 { 142 {
@@ -157,13 +149,10 @@ void MailThreadTest::testIndexInMixedOrder()
157 149
158 //Ensure we find the thread leader still 150 //Ensure we find the thread leader still
159 { 151 {
160 auto job = Store::fetchAll<Mail>(query) 152 auto mails = Store::read<Mail>(query);
161 .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { 153 QCOMPARE(mails.size(), 1);
162 QCOMPARE(mails.size(), 1); 154 auto mail = mails.first();
163 auto mail = *mails.first(); 155 QCOMPARE(mail.getSubject(), QString::fromLatin1("Re: Re: 1"));
164 QCOMPARE(mail.getSubject(), QString::fromLatin1("Re: Re: 1"));
165 });
166 VERIFYEXEC(job);
167 } 156 }
168 157
169 { 158 {
@@ -176,20 +165,13 @@ void MailThreadTest::testIndexInMixedOrder()
176 165
177 //Ensure the thread is complete 166 //Ensure the thread is complete
178 { 167 {
179 Sink::Query query; 168 auto query = Sink::Query::completeThread(threadLeader);
180 query.filter(SinkResource(mResourceInstanceIdentifier));
181 query.ids << threadLeader.identifier();
182 query.request<Mail::Subject>().request<Mail::MimeMessage>().request<Mail::Folder>().request<Mail::Date>(); 169 query.request<Mail::Subject>().request<Mail::MimeMessage>().request<Mail::Folder>().request<Mail::Date>();
183 query.sort<Mail::Date>(); 170
184 query.bloom<Mail::ThreadId>(); 171 auto mails = Store::read<Mail>(query);
185 172 QCOMPARE(mails.size(), 3);
186 auto job = Store::fetchAll<Mail>(query) 173 auto mail = mails.first();
187 .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { 174 QCOMPARE(mail.getSubject(), QString::fromLatin1("Re: Re: 1"));
188 QCOMPARE(mails.size(), 3);
189 auto mail = *mails.first();
190 QCOMPARE(mail.getSubject(), QString::fromLatin1("Re: Re: 1"));
191 });
192 VERIFYEXEC(job);
193 } 175 }
194 176
195 /* VERIFYEXEC(Store::remove(mail)); */ 177 /* VERIFYEXEC(Store::remove(mail)); */
diff --git a/tests/querytest.cpp b/tests/querytest.cpp
index ab2a7e5..be1e0f6 100644
--- a/tests/querytest.cpp
+++ b/tests/querytest.cpp
@@ -12,6 +12,7 @@
12#include "test.h" 12#include "test.h"
13#include "testutils.h" 13#include "testutils.h"
14 14
15using namespace Sink;
15using namespace Sink::ApplicationDomain; 16using namespace Sink::ApplicationDomain;
16 17
17/** 18/**
@@ -52,7 +53,7 @@ private slots:
52 query.liveQuery = true; 53 query.liveQuery = true;
53 54
54 // We fetch before the data is available and rely on the live query mechanism to deliver the actual data 55 // We fetch before the data is available and rely on the live query mechanism to deliver the actual data
55 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Mail>(query); 56 auto model = Sink::Store::loadModel<Mail>(query);
56 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 57 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
57 QCOMPARE(model->rowCount(), 0); 58 QCOMPARE(model->rowCount(), 0);
58 } 59 }
@@ -62,8 +63,8 @@ private slots:
62 { 63 {
63 // Setup 64 // Setup
64 { 65 {
65 Sink::ApplicationDomain::Mail mail("sink.dummy.instance1"); 66 Mail mail("sink.dummy.instance1");
66 Sink::Store::create<Sink::ApplicationDomain::Mail>(mail).exec().waitForFinished(); 67 Sink::Store::create<Mail>(mail).exec().waitForFinished();
67 } 68 }
68 69
69 // Test 70 // Test
@@ -72,7 +73,7 @@ private slots:
72 query.liveQuery = true; 73 query.liveQuery = true;
73 74
74 // We fetch before the data is available and rely on the live query mechanism to deliver the actual data 75 // We fetch before the data is available and rely on the live query mechanism to deliver the actual data
75 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Mail>(query); 76 auto model = Sink::Store::loadModel<Mail>(query);
76 QTRY_COMPARE(model->rowCount(), 1); 77 QTRY_COMPARE(model->rowCount(), 1);
77 } 78 }
78 79
@@ -80,8 +81,8 @@ private slots:
80 { 81 {
81 // Setup 82 // Setup
82 { 83 {
83 Sink::ApplicationDomain::Mail mail("sink.dummy.instance1"); 84 Mail mail("sink.dummy.instance1");
84 Sink::Store::create<Sink::ApplicationDomain::Mail>(mail).exec().waitForFinished(); 85 Sink::Store::create<Mail>(mail).exec().waitForFinished();
85 } 86 }
86 87
87 // Test 88 // Test
@@ -93,7 +94,7 @@ private slots:
93 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 94 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
94 95
95 // We fetch after the data is available and don't rely on the live query mechanism to deliver the actual data 96 // We fetch after the data is available and don't rely on the live query mechanism to deliver the actual data
96 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Mail>(query); 97 auto model = Sink::Store::loadModel<Mail>(query);
97 98
98 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 99 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
99 QCOMPARE(model->rowCount(), 1); 100 QCOMPARE(model->rowCount(), 1);
@@ -125,7 +126,7 @@ private slots:
125 auto model = Sink::Store::loadModel<Mail>(query); 126 auto model = Sink::Store::loadModel<Mail>(query);
126 QTRY_COMPARE(model->rowCount(), 1); 127 QTRY_COMPARE(model->rowCount(), 1);
127 128
128 auto mail = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Mail::Ptr>(); 129 auto mail = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Mail::Ptr>();
129 { 130 {
130 mail->setFolder("folder2"); 131 mail->setFolder("folder2");
131 Sink::Store::modify<Mail>(*mail).exec().waitForFinished(); 132 Sink::Store::modify<Mail>(*mail).exec().waitForFinished();
@@ -144,9 +145,9 @@ private slots:
144 QByteArray id; 145 QByteArray id;
145 // Setup 146 // Setup
146 { 147 {
147 Sink::ApplicationDomain::Mail mail("sink.dummy.instance1"); 148 Mail mail("sink.dummy.instance1");
148 Sink::Store::create<Sink::ApplicationDomain::Mail>(mail).exec().waitForFinished(); 149 Sink::Store::create<Mail>(mail).exec().waitForFinished();
149 Sink::Store::create<Sink::ApplicationDomain::Mail>(mail).exec().waitForFinished(); 150 Sink::Store::create<Mail>(mail).exec().waitForFinished();
150 151
151 Sink::Query query; 152 Sink::Query query;
152 query.resources << "sink.dummy.instance1"; 153 query.resources << "sink.dummy.instance1";
@@ -155,17 +156,17 @@ private slots:
155 Sink::Store::synchronize(query).exec().waitForFinished(); 156 Sink::Store::synchronize(query).exec().waitForFinished();
156 157
157 // We fetch before the data is available and rely on the live query mechanism to deliver the actual data 158 // We fetch before the data is available and rely on the live query mechanism to deliver the actual data
158 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Mail>(query); 159 auto model = Sink::Store::loadModel<Mail>(query);
159 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 160 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
160 QVERIFY(model->rowCount() >= 1); 161 QVERIFY(model->rowCount() >= 1);
161 id = model->index(0, 0).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Mail::Ptr>()->identifier(); 162 id = model->index(0, 0).data(Sink::Store::DomainObjectRole).value<Mail::Ptr>()->identifier();
162 } 163 }
163 164
164 // Test 165 // Test
165 Sink::Query query; 166 Sink::Query query;
166 query.resources << "sink.dummy.instance1"; 167 query.resources << "sink.dummy.instance1";
167 query.ids << id; 168 query.ids << id;
168 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Mail>(query); 169 auto model = Sink::Store::loadModel<Mail>(query);
169 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 170 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
170 QCOMPARE(model->rowCount(), 1); 171 QCOMPARE(model->rowCount(), 1);
171 } 172 }
@@ -174,8 +175,8 @@ private slots:
174 { 175 {
175 // Setup 176 // Setup
176 { 177 {
177 Sink::ApplicationDomain::Folder folder("sink.dummy.instance1"); 178 Folder folder("sink.dummy.instance1");
178 Sink::Store::create<Sink::ApplicationDomain::Folder>(folder).exec().waitForFinished(); 179 Sink::Store::create<Folder>(folder).exec().waitForFinished();
179 } 180 }
180 181
181 // Test 182 // Test
@@ -184,9 +185,9 @@ private slots:
184 query.liveQuery = true; 185 query.liveQuery = true;
185 186
186 // We fetch before the data is available and rely on the live query mechanism to deliver the actual data 187 // We fetch before the data is available and rely on the live query mechanism to deliver the actual data
187 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Folder>(query); 188 auto model = Sink::Store::loadModel<Folder>(query);
188 QTRY_COMPARE(model->rowCount(), 1); 189 QTRY_COMPARE(model->rowCount(), 1);
189 auto folderEntity = model->index(0, 0).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Folder::Ptr>(); 190 auto folderEntity = model->index(0, 0).data(Sink::Store::DomainObjectRole).value<Folder::Ptr>();
190 QVERIFY(!folderEntity->identifier().isEmpty()); 191 QVERIFY(!folderEntity->identifier().isEmpty());
191 } 192 }
192 193
@@ -194,8 +195,8 @@ private slots:
194 { 195 {
195 // Setup 196 // Setup
196 { 197 {
197 Sink::ApplicationDomain::Folder folder("sink.dummy.instance1"); 198 Folder folder("sink.dummy.instance1");
198 Sink::Store::create<Sink::ApplicationDomain::Folder>(folder).exec().waitForFinished(); 199 Sink::Store::create<Folder>(folder).exec().waitForFinished();
199 200
200 Sink::Query query; 201 Sink::Query query;
201 query.resources << "sink.dummy.instance1"; 202 query.resources << "sink.dummy.instance1";
@@ -203,16 +204,16 @@ private slots:
203 // Ensure all local data is processed 204 // Ensure all local data is processed
204 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 205 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
205 206
206 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Folder>(query); 207 auto model = Sink::Store::loadModel<Folder>(query);
207 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 208 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
208 QCOMPARE(model->rowCount(), 1); 209 QCOMPARE(model->rowCount(), 1);
209 210
210 auto folderEntity = model->index(0, 0).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Folder::Ptr>(); 211 auto folderEntity = model->index(0, 0).data(Sink::Store::DomainObjectRole).value<Folder::Ptr>();
211 QVERIFY(!folderEntity->identifier().isEmpty()); 212 QVERIFY(!folderEntity->identifier().isEmpty());
212 213
213 Sink::ApplicationDomain::Folder subfolder("sink.dummy.instance1"); 214 Folder subfolder("sink.dummy.instance1");
214 subfolder.setProperty("parent", folderEntity->identifier()); 215 subfolder.setProperty("parent", folderEntity->identifier());
215 Sink::Store::create<Sink::ApplicationDomain::Folder>(subfolder).exec().waitForFinished(); 216 Sink::Store::create<Folder>(subfolder).exec().waitForFinished();
216 } 217 }
217 218
218 // Test 219 // Test
@@ -224,7 +225,7 @@ private slots:
224 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 225 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
225 226
226 // We fetch after the data is available and don't rely on the live query mechanism to deliver the actual data 227 // We fetch after the data is available and don't rely on the live query mechanism to deliver the actual data
227 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Folder>(query); 228 auto model = Sink::Store::loadModel<Folder>(query);
228 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 229 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
229 QCOMPARE(model->rowCount(), 1); 230 QCOMPARE(model->rowCount(), 1);
230 model->fetchMore(model->index(0, 0)); 231 model->fetchMore(model->index(0, 0));
@@ -236,30 +237,30 @@ private slots:
236 { 237 {
237 // Setup 238 // Setup
238 { 239 {
239 Sink::ApplicationDomain::Mail mail("sink.dummy.instance1"); 240 Mail mail("sink.dummy.instance1");
240 mail.setProperty("uid", "test1"); 241 mail.setProperty("uid", "test1");
241 mail.setProperty("sender", "doe@example.org"); 242 mail.setProperty("sender", "doe@example.org");
242 Sink::Store::create<Sink::ApplicationDomain::Mail>(mail).exec().waitForFinished(); 243 Sink::Store::create<Mail>(mail).exec().waitForFinished();
243 } 244 }
244 245
245 { 246 {
246 Sink::ApplicationDomain::Mail mail("sink.dummy.instance1"); 247 Mail mail("sink.dummy.instance1");
247 mail.setProperty("uid", "test2"); 248 mail.setProperty("uid", "test2");
248 mail.setProperty("sender", "doe@example.org"); 249 mail.setProperty("sender", "doe@example.org");
249 Sink::Store::create<Sink::ApplicationDomain::Mail>(mail).exec().waitForFinished(); 250 Sink::Store::create<Mail>(mail).exec().waitForFinished();
250 } 251 }
251 252
252 // Test 253 // Test
253 Sink::Query query; 254 Sink::Query query;
254 query.resources << "sink.dummy.instance1"; 255 query.resources << "sink.dummy.instance1";
255 query.liveQuery = false; 256 query.liveQuery = false;
256 query += Sink::Query::PropertyFilter("uid", "test1"); 257 query.filter<Mail::Uid>("test1");
257 258
258 // Ensure all local data is processed 259 // Ensure all local data is processed
259 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 260 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
260 261
261 // We fetch before the data is available and rely on the live query mechanism to deliver the actual data 262 // We fetch before the data is available and rely on the live query mechanism to deliver the actual data
262 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Mail>(query); 263 auto model = Sink::Store::loadModel<Mail>(query);
263 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 264 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
264 QCOMPARE(model->rowCount(), 1); 265 QCOMPARE(model->rowCount(), 1);
265 } 266 }
@@ -267,10 +268,10 @@ private slots:
267 void testMailByFolder() 268 void testMailByFolder()
268 { 269 {
269 // Setup 270 // Setup
270 Sink::ApplicationDomain::Folder::Ptr folderEntity; 271 Folder::Ptr folderEntity;
271 { 272 {
272 Sink::ApplicationDomain::Folder folder("sink.dummy.instance1"); 273 Folder folder("sink.dummy.instance1");
273 Sink::Store::create<Sink::ApplicationDomain::Folder>(folder).exec().waitForFinished(); 274 Sink::Store::create<Folder>(folder).exec().waitForFinished();
274 275
275 Sink::Query query; 276 Sink::Query query;
276 query.resources << "sink.dummy.instance1"; 277 query.resources << "sink.dummy.instance1";
@@ -278,29 +279,29 @@ private slots:
278 // Ensure all local data is processed 279 // Ensure all local data is processed
279 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 280 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
280 281
281 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Folder>(query); 282 auto model = Sink::Store::loadModel<Folder>(query);
282 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 283 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
283 QCOMPARE(model->rowCount(), 1); 284 QCOMPARE(model->rowCount(), 1);
284 285
285 folderEntity = model->index(0, 0).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Folder::Ptr>(); 286 folderEntity = model->index(0, 0).data(Sink::Store::DomainObjectRole).value<Folder::Ptr>();
286 QVERIFY(!folderEntity->identifier().isEmpty()); 287 QVERIFY(!folderEntity->identifier().isEmpty());
287 288
288 Sink::ApplicationDomain::Mail mail("sink.dummy.instance1"); 289 Mail mail("sink.dummy.instance1");
289 mail.setProperty("uid", "test1"); 290 mail.setProperty("uid", "test1");
290 mail.setProperty("folder", folderEntity->identifier()); 291 mail.setProperty("folder", folderEntity->identifier());
291 Sink::Store::create<Sink::ApplicationDomain::Mail>(mail).exec().waitForFinished(); 292 Sink::Store::create<Mail>(mail).exec().waitForFinished();
292 } 293 }
293 294
294 // Test 295 // Test
295 Sink::Query query; 296 Sink::Query query;
296 query.resources << "sink.dummy.instance1"; 297 query.resources << "sink.dummy.instance1";
297 query += Sink::Query::PropertyFilter("folder", *folderEntity); 298 query.filter<Mail::Folder>(*folderEntity);
298 299
299 // Ensure all local data is processed 300 // Ensure all local data is processed
300 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 301 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
301 302
302 // We fetch before the data is available and rely on the live query mechanism to deliver the actual data 303 // We fetch before the data is available and rely on the live query mechanism to deliver the actual data
303 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Mail>(query); 304 auto model = Sink::Store::loadModel<Mail>(query);
304 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 305 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
305 QCOMPARE(model->rowCount(), 1); 306 QCOMPARE(model->rowCount(), 1);
306 } 307 }
@@ -363,10 +364,10 @@ private slots:
363 void testMailByFolderSortedByDate() 364 void testMailByFolderSortedByDate()
364 { 365 {
365 // Setup 366 // Setup
366 Sink::ApplicationDomain::Folder::Ptr folderEntity; 367 Folder::Ptr folderEntity;
367 { 368 {
368 Sink::ApplicationDomain::Folder folder("sink.dummy.instance1"); 369 Folder folder("sink.dummy.instance1");
369 Sink::Store::create<Sink::ApplicationDomain::Folder>(folder).exec().waitForFinished(); 370 Sink::Store::create<Folder>(folder).exec().waitForFinished();
370 371
371 Sink::Query query; 372 Sink::Query query;
372 query.resources << "sink.dummy.instance1"; 373 query.resources << "sink.dummy.instance1";
@@ -374,71 +375,71 @@ private slots:
374 // Ensure all local data is processed 375 // Ensure all local data is processed
375 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 376 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
376 377
377 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Folder>(query); 378 auto model = Sink::Store::loadModel<Folder>(query);
378 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 379 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
379 QCOMPARE(model->rowCount(), 1); 380 QCOMPARE(model->rowCount(), 1);
380 381
381 folderEntity = model->index(0, 0).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Folder::Ptr>(); 382 folderEntity = model->index(0, 0).data(Sink::Store::DomainObjectRole).value<Folder::Ptr>();
382 QVERIFY(!folderEntity->identifier().isEmpty()); 383 QVERIFY(!folderEntity->identifier().isEmpty());
383 384
384 const auto date = QDateTime(QDate(2015, 7, 7), QTime(12, 0)); 385 const auto date = QDateTime(QDate(2015, 7, 7), QTime(12, 0));
385 { 386 {
386 Sink::ApplicationDomain::Mail mail("sink.dummy.instance1"); 387 Mail mail("sink.dummy.instance1");
387 mail.setProperty("uid", "testSecond"); 388 mail.setProperty("uid", "testSecond");
388 mail.setProperty("folder", folderEntity->identifier()); 389 mail.setProperty("folder", folderEntity->identifier());
389 mail.setProperty("date", date.addDays(-1)); 390 mail.setProperty("date", date.addDays(-1));
390 Sink::Store::create<Sink::ApplicationDomain::Mail>(mail).exec().waitForFinished(); 391 Sink::Store::create<Mail>(mail).exec().waitForFinished();
391 } 392 }
392 { 393 {
393 Sink::ApplicationDomain::Mail mail("sink.dummy.instance1"); 394 Mail mail("sink.dummy.instance1");
394 mail.setProperty("uid", "testLatest"); 395 mail.setProperty("uid", "testLatest");
395 mail.setProperty("folder", folderEntity->identifier()); 396 mail.setProperty("folder", folderEntity->identifier());
396 mail.setProperty("date", date); 397 mail.setProperty("date", date);
397 Sink::Store::create<Sink::ApplicationDomain::Mail>(mail).exec().waitForFinished(); 398 Sink::Store::create<Mail>(mail).exec().waitForFinished();
398 } 399 }
399 { 400 {
400 Sink::ApplicationDomain::Mail mail("sink.dummy.instance1"); 401 Mail mail("sink.dummy.instance1");
401 mail.setProperty("uid", "testLast"); 402 mail.setProperty("uid", "testLast");
402 mail.setProperty("folder", folderEntity->identifier()); 403 mail.setProperty("folder", folderEntity->identifier());
403 mail.setProperty("date", date.addDays(-2)); 404 mail.setProperty("date", date.addDays(-2));
404 Sink::Store::create<Sink::ApplicationDomain::Mail>(mail).exec().waitForFinished(); 405 Sink::Store::create<Mail>(mail).exec().waitForFinished();
405 } 406 }
406 } 407 }
407 408
408 // Test 409 // Test
409 Sink::Query query; 410 Sink::Query query;
410 query.resources << "sink.dummy.instance1"; 411 query.resources << "sink.dummy.instance1";
411 query += Sink::Query::PropertyFilter("folder", *folderEntity); 412 query.filter<Mail::Folder>(*folderEntity);
412 query.sortProperty = "date"; 413 query.sort<Mail::Date>();
413 query.limit = 1; 414 query.limit = 1;
414 query.liveQuery = false; 415 query.liveQuery = false;
415 416
416 // Ensure all local data is processed 417 // Ensure all local data is processed
417 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished(); 418 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
418 419
419 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Mail>(query); 420 auto model = Sink::Store::loadModel<Mail>(query);
420 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 421 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
421 // The model is not sorted, but the limited set is sorted, so we can only test for the latest result. 422 // The model is not sorted, but the limited set is sorted, so we can only test for the latest result.
422 QCOMPARE(model->rowCount(), 1); 423 QCOMPARE(model->rowCount(), 1);
423 QCOMPARE(model->index(0, 0).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Mail::Ptr>()->getProperty("uid").toByteArray(), QByteArray("testLatest")); 424 QCOMPARE(model->index(0, 0).data(Sink::Store::DomainObjectRole).value<Mail::Ptr>()->getProperty("uid").toByteArray(), QByteArray("testLatest"));
424 425
425 model->fetchMore(QModelIndex()); 426 model->fetchMore(QModelIndex());
426 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 427 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
427 QCOMPARE(model->rowCount(), 2); 428 QCOMPARE(model->rowCount(), 2);
428 // We can't make any assumptions about the order of the indexes 429 // We can't make any assumptions about the order of the indexes
429 // QCOMPARE(model->index(1, 0).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Mail::Ptr>()->getProperty("uid").toByteArray(), QByteArray("testSecond")); 430 // QCOMPARE(model->index(1, 0).data(Sink::Store::DomainObjectRole).value<Mail::Ptr>()->getProperty("uid").toByteArray(), QByteArray("testSecond"));
430 } 431 }
431 432
432 void testReactToNewResource() 433 void testReactToNewResource()
433 { 434 {
434 Sink::Query query; 435 Sink::Query query;
435 query.liveQuery = true; 436 query.liveQuery = true;
436 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Folder>(query); 437 auto model = Sink::Store::loadModel<Folder>(query);
437 QTRY_COMPARE(model->rowCount(QModelIndex()), 0); 438 QTRY_COMPARE(model->rowCount(QModelIndex()), 0);
438 439
439 auto res = Sink::ApplicationDomain::DummyResource::create(""); 440 auto res = DummyResource::create("");
440 VERIFYEXEC(Sink::Store::create(res)); 441 VERIFYEXEC(Sink::Store::create(res));
441 auto folder = Sink::ApplicationDomain::Folder::create(res.identifier()); 442 auto folder = Folder::create(res.identifier());
442 VERIFYEXEC(Sink::Store::create(folder)); 443 VERIFYEXEC(Sink::Store::create(folder));
443 QTRY_COMPARE(model->rowCount(QModelIndex()), 1); 444 QTRY_COMPARE(model->rowCount(QModelIndex()), 1);
444 445