summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/datastorequery.cpp22
-rw-r--r--tests/querytest.cpp6
2 files changed, 18 insertions, 10 deletions
diff --git a/common/datastorequery.cpp b/common/datastorequery.cpp
index 9e61a3d..b77dfc9 100644
--- a/common/datastorequery.cpp
+++ b/common/datastorequery.cpp
@@ -267,14 +267,14 @@ public:
267 for (auto &aggregator : mAggregators) { 267 for (auto &aggregator : mAggregators) {
268 aggregator.reset(); 268 aggregator.reset();
269 } 269 }
270 270 QVector<QByteArray> reducedAndFilteredResults;
271 for (const auto &r : results) { 271 for (const auto &r : results) {
272 readEntity(r, [&, this](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation operation) { 272 readEntity(r, [&, this](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation operation) {
273 //We need to apply all property filters that we have until the reduction, because the index lookup was unfiltered. 273 //We need to apply all property filters that we have until the reduction, because the index lookup was unfiltered.
274 if (!matchesFilter(entity)) { 274 if (!matchesFilter(entity)) {
275 return; 275 return;
276 } 276 }
277 277 reducedAndFilteredResults << r;
278 Q_ASSERT(operation != Sink::Operation_Removal); 278 Q_ASSERT(operation != Sink::Operation_Removal);
279 for (auto &aggregator : mAggregators) { 279 for (auto &aggregator : mAggregators) {
280 if (!aggregator.property.isEmpty()) { 280 if (!aggregator.property.isEmpty()) {
@@ -294,14 +294,18 @@ public:
294 for (auto &aggregator : mAggregators) { 294 for (auto &aggregator : mAggregators) {
295 aggregateValues.insert(aggregator.resultProperty, aggregator.result()); 295 aggregateValues.insert(aggregator.resultProperty, aggregator.result());
296 } 296 }
297 return {selectionResult, results, aggregateValues}; 297 return {selectionResult, reducedAndFilteredResults, aggregateValues};
298 } 298 }
299 299
300 bool next(const std::function<void(const ResultSet::Result &)> &callback) Q_DECL_OVERRIDE { 300 bool next(const std::function<void(const ResultSet::Result &)> &callback) Q_DECL_OVERRIDE {
301 bool foundValue = false; 301 bool foundValue = false;
302 while(!foundValue && mSource->next([this, callback, &foundValue](const ResultSet::Result &result) { 302 while(!foundValue && mSource->next([this, callback, &foundValue](const ResultSet::Result &result) {
303 const auto reductionValue = [&] { 303 const auto reductionValue = [&] {
304 if (result.operation == Sink::Operation_Removal) { 304 const auto v = result.entity.getProperty(mReductionProperty);
305 //Because we also get Operation_Removal for filtered entities. We use the fact that actually removed entites
306 //won't have the property to reduce on.
307 //TODO: Perhaps find a cleaner solutoin than abusing Operation::Removed for filtered properties.
308 if (v.isNull() && result.operation == Sink::Operation_Removal) {
305 //For removals we have to read the last revision to get a value, and thus be able to find the correct thread. 309 //For removals we have to read the last revision to get a value, and thus be able to find the correct thread.
306 QVariant reductionValue; 310 QVariant reductionValue;
307 readPrevious(result.entity.identifier(), [&] (const ApplicationDomain::ApplicationDomainType &prev) { 311 readPrevious(result.entity.identifier(), [&] (const ApplicationDomain::ApplicationDomainType &prev) {
@@ -309,10 +313,15 @@ public:
309 }); 313 });
310 return reductionValue; 314 return reductionValue;
311 } else { 315 } else {
312 return result.entity.getProperty(mReductionProperty); 316 return v;
313 } 317 }
314 }(); 318 }();
315 const auto &reductionValueBa = getByteArray(reductionValue); 319 if (reductionValue.isNull()) {
320 //We failed to find a value to reduce on, so ignore this entity.
321 //Can happen if the entity was already removed and we have no previous revision.
322 return;
323 }
324 const auto reductionValueBa = getByteArray(reductionValue);
316 if (!mReducedValues.contains(reductionValueBa)) { 325 if (!mReducedValues.contains(reductionValueBa)) {
317 //Only reduce every value once. 326 //Only reduce every value once.
318 mReducedValues.insert(reductionValueBa); 327 mReducedValues.insert(reductionValueBa);
@@ -356,7 +365,6 @@ public:
356 } 365 }
357 } 366 }
358 } 367 }
359 return false;
360 })) 368 }))
361 {} 369 {}
362 return foundValue; 370 return foundValue;
diff --git a/tests/querytest.cpp b/tests/querytest.cpp
index f65d477..52f0024 100644
--- a/tests/querytest.cpp
+++ b/tests/querytest.cpp
@@ -1211,7 +1211,7 @@ private slots:
1211 Query query; 1211 Query query;
1212 query.setId("testLivequeryThreadleaderChange"); 1212 query.setId("testLivequeryThreadleaderChange");
1213 query.setFlags(Query::LiveQuery); 1213 query.setFlags(Query::LiveQuery);
1214 query.reduce<Mail::Folder>(Query::Reduce::Selector::max<Mail::Date>()).count("count").collect<Mail::Folder>("folders"); 1214 query.reduce<Mail::Folder>(Query::Reduce::Selector::max<Mail::Date>()).count().collect<Mail::Folder>();
1215 query.sort<Mail::Date>(); 1215 query.sort<Mail::Date>();
1216 query.request<Mail::MessageId>(); 1216 query.request<Mail::MessageId>();
1217 query.filter<Mail::Important>(false); 1217 query.filter<Mail::Important>(false);
@@ -1224,8 +1224,8 @@ private slots:
1224 { 1224 {
1225 auto mail = model->data(model->index(0, 0, QModelIndex{}), Sink::Store::DomainObjectRole).value<Mail::Ptr>(); 1225 auto mail = model->data(model->index(0, 0, QModelIndex{}), Sink::Store::DomainObjectRole).value<Mail::Ptr>();
1226 QCOMPARE(mail->getMessageId(), QByteArray{"mail1"}); 1226 QCOMPARE(mail->getMessageId(), QByteArray{"mail1"});
1227 QCOMPARE(mail->getProperty("count").toInt(), 2); 1227 QCOMPARE(mail->count(), 2);
1228 QCOMPARE(mail->getProperty("folders").toList().size(), 2); 1228 QCOMPARE(mail->getCollectedProperty<Mail::Folder>().size(), 2);
1229 } 1229 }
1230 } 1230 }
1231 1231