summaryrefslogtreecommitdiffstats
path: root/common/queryrunner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/queryrunner.cpp')
-rw-r--r--common/queryrunner.cpp24
1 files changed, 19 insertions, 5 deletions
diff --git a/common/queryrunner.cpp b/common/queryrunner.cpp
index 052db39..11459f1 100644
--- a/common/queryrunner.cpp
+++ b/common/queryrunner.cpp
@@ -20,6 +20,7 @@
20 20
21#include <limits> 21#include <limits>
22#include <QTime> 22#include <QTime>
23#include <QPointer>
23 24
24#include "commands.h" 25#include "commands.h"
25#include "log.h" 26#include "log.h"
@@ -71,6 +72,7 @@ QueryRunner<DomainType>::QueryRunner(const Sink::Query &query, const Sink::Resou
71 if (query.limit && query.sortProperty.isEmpty()) { 72 if (query.limit && query.sortProperty.isEmpty()) {
72 SinkWarning() << "A limited query without sorting is typically a bad idea."; 73 SinkWarning() << "A limited query without sorting is typically a bad idea.";
73 } 74 }
75 auto guardPtr = QPointer<QObject>(&guard);
74 // We delegate loading of initial data to the result provider, so it can decide for itself what it needs to load. 76 // We delegate loading of initial data to the result provider, so it can decide for itself what it needs to load.
75 mResultProvider->setFetcher([=](const typename DomainType::Ptr &parent) { 77 mResultProvider->setFetcher([=](const typename DomainType::Ptr &parent) {
76 const QByteArray parentId = parent ? parent->identifier() : QByteArray(); 78 const QByteArray parentId = parent ? parent->identifier() : QByteArray();
@@ -81,12 +83,20 @@ QueryRunner<DomainType>::QueryRunner(const Sink::Query &query, const Sink::Resou
81 worker.executeInitialQuery(query, parent, *resultProvider, mOffset[parentId], mBatchSize); 83 worker.executeInitialQuery(query, parent, *resultProvider, mOffset[parentId], mBatchSize);
82 resultProvider->initialResultSetComplete(parent); 84 resultProvider->initialResultSetComplete(parent);
83 } else { 85 } else {
84 async::run<QPair<qint64, qint64> >([=]() { 86 auto resultTransformation = mResultTransformation;
85 QueryWorker<DomainType> worker(query, instanceIdentifier, factory, bufferType, mResultTransformation); 87 auto offset = mOffset[parentId];
86 const auto newRevisionAndReplayedEntities = worker.executeInitialQuery(query, parent, *resultProvider, mOffset[parentId], mBatchSize); 88 auto batchSize = mBatchSize;
89 //The lambda will be executed in a separate thread, so we're extra careful
90 async::run<QPair<qint64, qint64> >([resultTransformation, offset, batchSize, query, bufferType, instanceIdentifier, factory, resultProvider, parent]() {
91 QueryWorker<DomainType> worker(query, instanceIdentifier, factory, bufferType, resultTransformation);
92 const auto newRevisionAndReplayedEntities = worker.executeInitialQuery(query, parent, *resultProvider, offset, batchSize);
87 return newRevisionAndReplayedEntities; 93 return newRevisionAndReplayedEntities;
88 }) 94 })
89 .template syncThen<void, QPair<qint64, qint64>>([=](const QPair<qint64, qint64> &newRevisionAndReplayedEntities) { 95 .template syncThen<void, QPair<qint64, qint64>>([this, parentId, query, parent, resultProvider, guardPtr](const QPair<qint64, qint64> &newRevisionAndReplayedEntities) {
96 if (!guardPtr) {
97 qWarning() << "The parent object is already gone";
98 return;
99 }
90 mOffset[parentId] += newRevisionAndReplayedEntities.second; 100 mOffset[parentId] += newRevisionAndReplayedEntities.second;
91 // Only send the revision replayed information if we're connected to the resource, there's no need to start the resource otherwise. 101 // Only send the revision replayed information if we're connected to the resource, there's no need to start the resource otherwise.
92 if (query.liveQuery) { 102 if (query.liveQuery) {
@@ -110,7 +120,11 @@ QueryRunner<DomainType>::QueryRunner(const Sink::Query &query, const Sink::Resou
110 const auto newRevisionAndReplayedEntities = worker.executeIncrementalQuery(query, *resultProvider); 120 const auto newRevisionAndReplayedEntities = worker.executeIncrementalQuery(query, *resultProvider);
111 return newRevisionAndReplayedEntities; 121 return newRevisionAndReplayedEntities;
112 }) 122 })
113 .template syncThen<void, QPair<qint64, qint64> >([query, this, resultProvider](const QPair<qint64, qint64> &newRevisionAndReplayedEntities) { 123 .template syncThen<void, QPair<qint64, qint64> >([query, this, resultProvider, guardPtr](const QPair<qint64, qint64> &newRevisionAndReplayedEntities) {
124 if (!guardPtr) {
125 qWarning() << "The parent object is already gone";
126 return;
127 }
114 // Only send the revision replayed information if we're connected to the resource, there's no need to start the resource otherwise. 128 // Only send the revision replayed information if we're connected to the resource, there's no need to start the resource otherwise.
115 mResourceAccess->sendRevisionReplayedCommand(newRevisionAndReplayedEntities.first); 129 mResourceAccess->sendRevisionReplayedCommand(newRevisionAndReplayedEntities.first);
116 resultProvider->setRevision(newRevisionAndReplayedEntities.first); 130 resultProvider->setRevision(newRevisionAndReplayedEntities.first);