summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/query.h6
-rw-r--r--common/queryrunner.cpp13
-rw-r--r--tests/querytest.cpp63
3 files changed, 75 insertions, 7 deletions
diff --git a/common/query.h b/common/query.h
index bb826aa..29cff78 100644
--- a/common/query.h
+++ b/common/query.h
@@ -103,6 +103,7 @@ public:
103 } 103 }
104 104
105 Query(Flags flags = Flags()) 105 Query(Flags flags = Flags())
106 : limit(0)
106 {} 107 {}
107 108
108 Query& operator+=(const Query& rhs) 109 Query& operator+=(const Query& rhs)
@@ -115,8 +116,6 @@ public:
115 requestedProperties += rhs.requestedProperties; 116 requestedProperties += rhs.requestedProperties;
116 parentProperty = rhs.parentProperty; 117 parentProperty = rhs.parentProperty;
117 liveQuery = rhs.liveQuery; 118 liveQuery = rhs.liveQuery;
118 syncOnDemand = rhs.syncOnDemand;
119 processAll = rhs.processAll;
120 return *this; 119 return *this;
121 } 120 }
122 121
@@ -133,8 +132,7 @@ public:
133 QByteArray parentProperty; 132 QByteArray parentProperty;
134 QByteArray sortProperty; 133 QByteArray sortProperty;
135 bool liveQuery; 134 bool liveQuery;
136 bool syncOnDemand; 135 int limit;
137 bool processAll;
138}; 136};
139 137
140} 138}
diff --git a/common/queryrunner.cpp b/common/queryrunner.cpp
index 1f645e8..2d188ae 100644
--- a/common/queryrunner.cpp
+++ b/common/queryrunner.cpp
@@ -18,7 +18,9 @@
18*/ 18*/
19#include "queryrunner.h" 19#include "queryrunner.h"
20 20
21#include <limits>
21#include <QTime> 22#include <QTime>
23
22#include "commands.h" 24#include "commands.h"
23#include "log.h" 25#include "log.h"
24#include "storage.h" 26#include "storage.h"
@@ -74,7 +76,7 @@ QueryRunner<DomainType>::QueryRunner(const Sink::Query &query, const Sink::Resou
74 mResourceAccess(resourceAccess), 76 mResourceAccess(resourceAccess),
75 mResultProvider(new ResultProvider<typename DomainType::Ptr>), 77 mResultProvider(new ResultProvider<typename DomainType::Ptr>),
76 mOffset(0), 78 mOffset(0),
77 mBatchSize(0) 79 mBatchSize(query.limit)
78{ 80{
79 Trace() << "Starting query"; 81 Trace() << "Starting query";
80 //We delegate loading of initial data to the result provider, os it can decide for itself what it needs to load. 82 //We delegate loading of initial data to the result provider, os it can decide for itself what it needs to load.
@@ -280,7 +282,7 @@ ResultSet QueryWorker<DomainType>::loadIncrementalResultSet(qint64 baseRevision,
280template<class DomainType> 282template<class DomainType>
281ResultSet QueryWorker<DomainType>::filterAndSortSet(ResultSet &resultSet, const std::function<bool(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject)> &filter, const Sink::Storage::NamedDatabase &db, bool initialQuery, const QByteArray &sortProperty) 283ResultSet QueryWorker<DomainType>::filterAndSortSet(ResultSet &resultSet, const std::function<bool(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject)> &filter, const Sink::Storage::NamedDatabase &db, bool initialQuery, const QByteArray &sortProperty)
282{ 284{
283 bool sortingRequired = false; 285 const bool sortingRequired = !sortProperty.isEmpty();
284 if (initialQuery && sortingRequired) { 286 if (initialQuery && sortingRequired) {
285 //Sort the complete set by reading the sort property and filling into a sorted map 287 //Sort the complete set by reading the sort property and filling into a sorted map
286 auto sortedMap = QSharedPointer<QMap<QByteArray, QByteArray>>::create(); 288 auto sortedMap = QSharedPointer<QMap<QByteArray, QByteArray>>::create();
@@ -290,7 +292,12 @@ ResultSet QueryWorker<DomainType>::filterAndSortSet(ResultSet &resultSet, const
290 //We're not interested in removals during the initial query 292 //We're not interested in removals during the initial query
291 if ((operation != Sink::Operation_Removal) && filter(domainObject)) { 293 if ((operation != Sink::Operation_Removal) && filter(domainObject)) {
292 if (!sortProperty.isEmpty()) { 294 if (!sortProperty.isEmpty()) {
293 sortedMap->insert(domainObject->getProperty(sortProperty).toString().toLatin1(), domainObject->identifier()); 295 const auto sortValue = domainObject->getProperty(sortProperty);
296 if (sortValue.canConvert<QDateTime>()) {
297 sortedMap->insert(QByteArray::number(std::numeric_limits<unsigned int>::max() - sortValue.toDateTime().toTime_t()), domainObject->identifier());
298 } else {
299 sortedMap->insert(sortValue.toString().toLatin1(), domainObject->identifier());
300 }
294 } else { 301 } else {
295 sortedMap->insert(domainObject->identifier(), domainObject->identifier()); 302 sortedMap->insert(domainObject->identifier(), domainObject->identifier());
296 } 303 }
diff --git a/tests/querytest.cpp b/tests/querytest.cpp
index 16376b9..50fc67f 100644
--- a/tests/querytest.cpp
+++ b/tests/querytest.cpp
@@ -259,6 +259,69 @@ private Q_SLOTS:
259 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); 259 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
260 QCOMPARE(model->rowCount(), 1); 260 QCOMPARE(model->rowCount(), 1);
261 } 261 }
262
263 void testMailByFolderSortedByDate()
264 {
265 //Setup
266 Sink::ApplicationDomain::Folder::Ptr folderEntity;
267 {
268 Sink::ApplicationDomain::Folder folder("org.kde.dummy.instance1");
269 Sink::Store::create<Sink::ApplicationDomain::Folder>(folder).exec().waitForFinished();
270
271 Sink::Query query;
272 query.resources << "org.kde.dummy.instance1";
273
274 //Ensure all local data is processed
275 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
276
277 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Folder>(query);
278 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
279 QCOMPARE(model->rowCount(), 1);
280
281 folderEntity = model->index(0, 0).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Folder::Ptr>();
282 QVERIFY(!folderEntity->identifier().isEmpty());
283
284 const auto date = QDateTime(QDate(2015, 7, 7), QTime(12, 0));
285 {
286 Sink::ApplicationDomain::Mail mail("org.kde.dummy.instance1");
287 mail.setProperty("uid", "testSecond");
288 mail.setProperty("folder", folderEntity->identifier());
289 mail.setProperty("date", date.addDays(-1));
290 Sink::Store::create<Sink::ApplicationDomain::Mail>(mail).exec().waitForFinished();
291 }
292 {
293 Sink::ApplicationDomain::Mail mail("org.kde.dummy.instance1");
294 mail.setProperty("uid", "testLatest");
295 mail.setProperty("folder", folderEntity->identifier());
296 mail.setProperty("date", date);
297 Sink::Store::create<Sink::ApplicationDomain::Mail>(mail).exec().waitForFinished();
298 }
299 {
300 Sink::ApplicationDomain::Mail mail("org.kde.dummy.instance1");
301 mail.setProperty("uid", "testLast");
302 mail.setProperty("folder", folderEntity->identifier());
303 mail.setProperty("date", date.addDays(-2));
304 Sink::Store::create<Sink::ApplicationDomain::Mail>(mail).exec().waitForFinished();
305 }
306 }
307
308 //Test
309 Sink::Query query;
310 query.resources << "org.kde.dummy.instance1";
311 query.propertyFilter.insert("folder", folderEntity->identifier());
312 query.sortProperty = "date";
313 query.limit = 1;
314
315 //Ensure all local data is processed
316 Sink::ResourceControl::flushMessageQueue(query.resources).exec().waitForFinished();
317
318 //We fetch before the data is available and rely on the live query mechanism to deliver the actual data
319 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Mail>(query);
320 QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
321 //The model is not sorted, but the limited set is sorted, so we can only test for the latest result.
322 QCOMPARE(model->rowCount(), 1);
323 QCOMPARE(model->index(0, 0).data(Sink::Store::DomainObjectRole).value<Sink::ApplicationDomain::Mail::Ptr>()->getProperty("uid").toByteArray(), QByteArray("testLatest"));
324 }
262}; 325};
263 326
264QTEST_MAIN(QueryTest) 327QTEST_MAIN(QueryTest)