summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2018-02-22 17:22:26 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2018-02-22 17:22:45 +0100
commit7287dae6c279583e5c5f0fafd8207341cc5a15af (patch)
tree22457f7d5a7a8a0e050f72072ee146db1b4d3ff8 /common
parent7748c2a5c1cc29a8c69ea051174e31b02af4a208 (diff)
downloadsink-7287dae6c279583e5c5f0fafd8207341cc5a15af.tar.gz
sink-7287dae6c279583e5c5f0fafd8207341cc5a15af.zip
Properly deal with filtered entities in reduced queries.
Filtered entities would still end up in the entities list before.
Diffstat (limited to 'common')
-rw-r--r--common/datastorequery.cpp22
1 files changed, 15 insertions, 7 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;