diff options
-rw-r--r-- | common/queryrunner.cpp | 62 |
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 | ||
274 | template<class DomainType> | 274 | template<class DomainType> |
275 | ResultSet QueryWorker<DomainType>::filterSet(const ResultSet &resultSet, const std::function<bool(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject)> &filter, const Sink::Storage::NamedDatabase &db, bool initialQuery) | 275 | ResultSet 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 | ||
304 | template<class DomainType> | 324 | template<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(); |