summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/queryrunner.cpp62
1 files changed, 41 insertions, 21 deletions
diff --git a/common/queryrunner.cpp b/common/queryrunner.cpp
index b6f5b51..fde5b04 100644
--- a/common/queryrunner.cpp
+++ b/common/queryrunner.cpp
@@ -55,7 +55,7 @@ private:
55 ResultSet loadInitialResultSet(const Sink::Query &query, Sink::Storage::Transaction &transaction, QSet<QByteArray> &remainingFilters); 55 ResultSet loadInitialResultSet(const Sink::Query &query, Sink::Storage::Transaction &transaction, QSet<QByteArray> &remainingFilters);
56 ResultSet loadIncrementalResultSet(qint64 baseRevision, const Sink::Query &query, Sink::Storage::Transaction &transaction, QSet<QByteArray> &remainingFilters); 56 ResultSet loadIncrementalResultSet(qint64 baseRevision, const Sink::Query &query, Sink::Storage::Transaction &transaction, QSet<QByteArray> &remainingFilters);
57 57
58 ResultSet filterSet(const ResultSet &resultSet, const std::function<bool(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject)> &filter, const Sink::Storage::NamedDatabase &db, bool initialQuery); 58 ResultSet filterAndSortSet(ResultSet &resultSet, const std::function<bool(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject)> &filter, const Sink::Storage::NamedDatabase &db, bool initialQuery, const QByteArray &sortProperty);
59 std::function<bool(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject)> getFilter(const QSet<QByteArray> remainingFilters, const Sink::Query &query); 59 std::function<bool(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject)> getFilter(const QSet<QByteArray> remainingFilters, const Sink::Query &query);
60 qint64 load(const Sink::Query &query, const std::function<ResultSet(Sink::Storage::Transaction &, QSet<QByteArray> &)> &baseSetRetriever, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, bool initialQuery); 60 qint64 load(const Sink::Query &query, const std::function<ResultSet(Sink::Storage::Transaction &, QSet<QByteArray> &)> &baseSetRetriever, Sink::ResultProviderInterface<typename DomainType::Ptr> &resultProvider, bool initialQuery);
61 61
@@ -272,33 +272,53 @@ ResultSet QueryWorker<DomainType>::loadIncrementalResultSet(qint64 baseRevision,
272} 272}
273 273
274template<class DomainType> 274template<class DomainType>
275ResultSet QueryWorker<DomainType>::filterSet(const ResultSet &resultSet, const std::function<bool(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject)> &filter, const Sink::Storage::NamedDatabase &db, bool initialQuery) 275ResultSet 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)
276{ 276{
277 auto resultSetPtr = QSharedPointer<ResultSet>::create(resultSet); 277 auto sortedMap = QSharedPointer<QMap<QByteArray, QByteArray>>::create();
278 278
279 //Read through the source values and return whatever matches the filter 279 if (initialQuery) {
280 std::function<bool(std::function<void(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &, Sink::Operation)>)> generator = [this, resultSetPtr, &db, filter, initialQuery](std::function<void(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &, Sink::Operation)> callback) -> bool { 280 while (resultSet.next()) {
281 if (resultSetPtr->next()) {
282 //readEntity is only necessary if we actually want to filter or know the operation type (but not a big deal if we do it always I guess) 281 //readEntity is only necessary if we actually want to filter or know the operation type (but not a big deal if we do it always I guess)
283 readEntity(db, resultSetPtr->id(), [this, filter, callback, initialQuery](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject, Sink::Operation operation) { 282 readEntity(db, resultSet.id(), [this, filter, initialQuery, sortedMap, sortProperty, &resultSet](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject, Sink::Operation operation) {
284 //Always remove removals, they probably don't match due to non-available properties 283 //We're not interested in removals during the initial query
285 if (filter(domainObject) || operation == Sink::Operation_Removal) { 284 if ((operation != Sink::Operation_Removal) && filter(domainObject)) {
286 if (initialQuery) { 285 if (!sortProperty.isEmpty()) {
287 //We're not interested in removals during the initial query 286 sortedMap->insert(domainObject->getProperty(sortProperty).toString().toLatin1(), domainObject->identifier());
288 if (operation != Sink::Operation_Removal) {
289 callback(domainObject, Sink::Operation_Creation);
290 }
291 } else { 287 } else {
292 callback(domainObject, operation); 288 sortedMap->insert(domainObject->identifier(), domainObject->identifier());
293 } 289 }
294 } 290 }
295 }); 291 });
296 return true;
297 } else {
298 return false;
299 } 292 }
300 }; 293
301 return ResultSet(generator); 294 auto iterator = QSharedPointer<QMapIterator<QByteArray, QByteArray> >::create(*sortedMap);
295 ResultSet::ValueGenerator generator = [this, iterator, sortedMap, &db, filter, initialQuery](std::function<void(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &, Sink::Operation)> callback) -> bool {
296 if (iterator->hasNext()) {
297 readEntity(db, iterator->next().value(), [this, filter, callback, initialQuery](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject, Sink::Operation operation) {
298 callback(domainObject, Sink::Operation_Creation);
299 });
300 return true;
301 }
302 return false;
303 };
304 return ResultSet(generator);
305 } else {
306 auto resultSetPtr = QSharedPointer<ResultSet>::create(resultSet);
307 ResultSet::ValueGenerator generator = [this, resultSetPtr, &db, filter, initialQuery](std::function<void(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &, Sink::Operation)> callback) -> bool {
308 if (resultSetPtr->next()) {
309 //readEntity is only necessary if we actually want to filter or know the operation type (but not a big deal if we do it always I guess)
310 readEntity(db, resultSetPtr->id(), [this, filter, callback, initialQuery](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject, Sink::Operation operation) {
311 //Always remove removals, they probably don't match due to non-available properties
312 if ((operation == Sink::Operation_Removal) || filter(domainObject)) {
313 callback(domainObject, operation);
314 }
315 });
316 return true;
317 }
318 return false;
319 };
320 return ResultSet(generator);
321 }
302} 322}
303 323
304template<class DomainType> 324template<class DomainType>
@@ -342,7 +362,7 @@ qint64 QueryWorker<DomainType>::load(const Sink::Query &query, const std::functi
342 QSet<QByteArray> remainingFilters; 362 QSet<QByteArray> remainingFilters;
343 auto resultSet = baseSetRetriever(transaction, remainingFilters); 363 auto resultSet = baseSetRetriever(transaction, remainingFilters);
344 Trace() << "Base set retrieved. " << time.elapsed(); 364 Trace() << "Base set retrieved. " << time.elapsed();
345 auto filteredSet = filterSet(resultSet, getFilter(remainingFilters, query), db, initialQuery); 365 auto filteredSet = filterAndSortSet(resultSet, getFilter(remainingFilters, query), db, initialQuery, query.sortProperty);
346 Trace() << "Filtered set retrieved. " << time.elapsed(); 366 Trace() << "Filtered set retrieved. " << time.elapsed();
347 replaySet(filteredSet, resultProvider, query.requestedProperties); 367 replaySet(filteredSet, resultProvider, query.requestedProperties);
348 Trace() << "Filtered set replayed. " << time.elapsed(); 368 Trace() << "Filtered set replayed. " << time.elapsed();