summaryrefslogtreecommitdiffstats
path: root/common/datastorequery.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-10-04 08:25:18 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-10-04 08:25:18 +0200
commitd6a01b3f82d626856001356c0875aa738a0346ac (patch)
treed77a6000e9d53be7844d72697496efa093b5f8ad /common/datastorequery.cpp
parent48ba18c92eede967afc4cf8894a3b06fd6a3c179 (diff)
downloadsink-d6a01b3f82d626856001356c0875aa738a0346ac.tar.gz
sink-d6a01b3f82d626856001356c0875aa738a0346ac.zip
Support for subqueries.
This allows us to match properties from a subquery. Unfortunately this also means that DataStoreQuery needs access to all type implementations to issue the subquery (for potentially another type).
Diffstat (limited to 'common/datastorequery.cpp')
-rw-r--r--common/datastorequery.cpp45
1 files changed, 43 insertions, 2 deletions
diff --git a/common/datastorequery.cpp b/common/datastorequery.cpp
index 3c4ae00..c4fbe13 100644
--- a/common/datastorequery.cpp
+++ b/common/datastorequery.cpp
@@ -21,6 +21,11 @@
21#include "log.h" 21#include "log.h"
22#include "entitybuffer.h" 22#include "entitybuffer.h"
23#include "entity_generated.h" 23#include "entity_generated.h"
24#include "applicationdomaintype.h"
25
26#include "folder.h"
27#include "mail.h"
28#include "event.h"
24 29
25using namespace Sink; 30using namespace Sink;
26 31
@@ -373,8 +378,44 @@ QVector<QByteArray> DataStoreQuery::indexLookup(const QByteArray &property, cons
373/* } */ 378/* } */
374/* } */ 379/* } */
375 380
381template <typename ... Args>
382QSharedPointer<DataStoreQuery> prepareQuery(const QByteArray &type, Args && ... args)
383{
384 if (type == ApplicationDomain::getTypeName<ApplicationDomain::Folder>()) {
385 return ApplicationDomain::TypeImplementation<ApplicationDomain::Folder>::prepareQuery(std::forward<Args>(args)...);
386 } else if (type == ApplicationDomain::getTypeName<ApplicationDomain::Mail>()) {
387 return ApplicationDomain::TypeImplementation<ApplicationDomain::Mail>::prepareQuery(std::forward<Args>(args)...);
388 } else if (type == ApplicationDomain::getTypeName<ApplicationDomain::Event>()) {
389 return ApplicationDomain::TypeImplementation<ApplicationDomain::Event>::prepareQuery(std::forward<Args>(args)...);
390 }
391 Q_ASSERT(false);
392 return QSharedPointer<DataStoreQuery>();
393}
394
395QByteArrayList DataStoreQuery::executeSubquery(const Query &subquery)
396{
397 Q_ASSERT(!subquery.type.isEmpty());
398 auto sub = prepareQuery(subquery.type, subquery, mTransaction);
399 auto result = sub->execute();
400 QByteArrayList ids;
401 while (result.next([&ids](const QByteArray &uid, const Sink::EntityBuffer &, Sink::Operation) {
402 ids << uid;
403 }))
404 {}
405 return ids;
406}
407
376void DataStoreQuery::setupQuery() 408void DataStoreQuery::setupQuery()
377{ 409{
410 for (const auto &k : mQuery.propertyFilter.keys()) {
411 const auto comparator = mQuery.propertyFilter.value(k);
412 if (comparator.value.canConvert<Query>()) {
413 SinkTrace() << "Executing subquery for property: " << k;
414 const auto result = executeSubquery(comparator.value.value<Query>());
415 mQuery.propertyFilter.insert(k, Query::Comparator(QVariant::fromValue(result), Query::Comparator::In));
416 }
417 }
418
378 FilterBase::Ptr baseSet; 419 FilterBase::Ptr baseSet;
379 QSet<QByteArray> remainingFilters = mQuery.getBaseFilters().keys().toSet(); 420 QSet<QByteArray> remainingFilters = mQuery.getBaseFilters().keys().toSet();
380 QByteArray appliedSorting; 421 QByteArray appliedSorting;
@@ -459,7 +500,7 @@ ResultSet DataStoreQuery::update(qint64 baseRevision)
459 SinkTrace() << "Changed: " << incrementalResultSet; 500 SinkTrace() << "Changed: " << incrementalResultSet;
460 mSource->add(incrementalResultSet); 501 mSource->add(incrementalResultSet);
461 ResultSet::ValueGenerator generator = [this](const ResultSet::Callback &callback) -> bool { 502 ResultSet::ValueGenerator generator = [this](const ResultSet::Callback &callback) -> bool {
462 if (mCollector->next([callback](Sink::Operation operation, const QByteArray &uid, const Sink::EntityBuffer &buffer) { 503 if (mCollector->next([this, callback](Sink::Operation operation, const QByteArray &uid, const Sink::EntityBuffer &buffer) {
463 SinkTrace() << "Got incremental result: " << uid << operation; 504 SinkTrace() << "Got incremental result: " << uid << operation;
464 callback(uid, buffer, operation); 505 callback(uid, buffer, operation);
465 })) 506 }))
@@ -477,7 +518,7 @@ ResultSet DataStoreQuery::execute()
477 SinkTrace() << "Executing query"; 518 SinkTrace() << "Executing query";
478 519
479 ResultSet::ValueGenerator generator = [this](const ResultSet::Callback &callback) -> bool { 520 ResultSet::ValueGenerator generator = [this](const ResultSet::Callback &callback) -> bool {
480 if (mCollector->next([callback](Sink::Operation operation, const QByteArray &uid, const Sink::EntityBuffer &buffer) { 521 if (mCollector->next([this, callback](Sink::Operation operation, const QByteArray &uid, const Sink::EntityBuffer &buffer) {
481 if (operation != Sink::Operation_Removal) { 522 if (operation != Sink::Operation_Removal) {
482 SinkTrace() << "Got initial result: " << uid << operation; 523 SinkTrace() << "Got initial result: " << uid << operation;
483 callback(uid, buffer, Sink::Operation_Creation); 524 callback(uid, buffer, Sink::Operation_Creation);