diff options
-rw-r--r-- | common/query.h | 6 | ||||
-rw-r--r-- | common/queryrunner.cpp | 13 | ||||
-rw-r--r-- | tests/querytest.cpp | 63 |
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, | |||
280 | template<class DomainType> | 282 | template<class DomainType> |
281 | ResultSet 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) | 283 | ResultSet 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 | ||
264 | QTEST_MAIN(QueryTest) | 327 | QTEST_MAIN(QueryTest) |