File indexing completed on 2024-05-12 05:26:02
0001 /* 0002 Copyright (c) 2015 Christian Mollekopf <mollekopf@kolabsys.com> 0003 0004 This library is free software; you can redistribute it and/or modify it 0005 under the terms of the GNU Library General Public License as published by 0006 the Free Software Foundation; either version 2 of the License, or (at your 0007 option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, but WITHOUT 0010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 0012 License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to the 0016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0017 02110-1301, USA. 0018 */ 0019 0020 #pragma once 0021 0022 #include <QObject> 0023 #include "resourcecontext.h" 0024 #include "resultprovider.h" 0025 #include "query.h" 0026 #include "log.h" 0027 #include "datastorequery.h" 0028 0029 /** 0030 * Base clase because you can't have the Q_OBJECT macro in template classes 0031 */ 0032 class QueryRunnerBase : public QObject 0033 { 0034 Q_OBJECT 0035 public: 0036 typedef std::function<void(Sink::ApplicationDomain::ApplicationDomainType &domainObject)> ResultTransformation; 0037 0038 /// Disable query updates on revision change. Used for testing only. 0039 void ignoreRevisionChanges() { 0040 mIgnoreRevisionChanges = true; 0041 } 0042 0043 /// Manually triger a revision change. Used for testing only. 0044 void triggerRevisionChange() { 0045 mIgnoreRevisionChanges = false; 0046 revisionChanged(); 0047 } 0048 0049 protected: 0050 typedef std::function<KAsync::Job<void>()> QueryFunction; 0051 0052 /** 0053 * Set the query to run 0054 */ 0055 void setQuery(const QueryFunction &query) 0056 { 0057 queryFunction = query; 0058 } 0059 0060 protected slots: 0061 /** 0062 * Rerun query with new revision 0063 */ 0064 void revisionChanged() 0065 { 0066 if (!mIgnoreRevisionChanges) { 0067 run().exec(); 0068 } 0069 } 0070 0071 private: 0072 /** 0073 * Starts query 0074 */ 0075 KAsync::Job<void> run() 0076 { 0077 return queryFunction(); 0078 } 0079 0080 QueryFunction queryFunction; 0081 bool mIgnoreRevisionChanges{false}; 0082 }; 0083 0084 /** 0085 * A QueryRunner runs a query and updates the corresponding result set. 0086 * 0087 * The lifetime of the QueryRunner is defined by the resut set (otherwise it's doing useless work), 0088 * and by how long a result set must be updated. If the query is a one off, the runner dies after the execution, 0089 * otherwise it lives on to react to changes, and updates the corresponding result set. 0090 * 0091 * QueryRunner has to keep ResourceAccess alive in order to keep getting updates. 0092 */ 0093 template <typename DomainType> 0094 class SINK_EXPORT QueryRunner : public QueryRunnerBase 0095 { 0096 public: 0097 QueryRunner(const Sink::Query &query, const Sink::ResourceContext &context, const QByteArray &bufferType, const Sink::Log::Context &logCtx); 0098 virtual ~QueryRunner(); 0099 0100 /** 0101 * Allows you to run a transformation on every result. 0102 * This transformation is executed in the query thread. 0103 */ 0104 void setResultTransformation(const ResultTransformation &transformation); 0105 0106 typename Sink::ResultEmitter<typename DomainType::Ptr>::Ptr emitter(); 0107 0108 /** 0109 * For testing only. 0110 */ 0111 void delayNextQuery(); 0112 0113 private: 0114 void fetch(const Sink::Query &query, const QByteArray &bufferType); 0115 KAsync::Job<void> incrementalFetch(const Sink::Query &query, const QByteArray &bufferType); 0116 0117 Sink::ResourceContext mResourceContext; 0118 QSharedPointer<Sink::ResourceAccessInterface> mResourceAccess; 0119 QSharedPointer<Sink::ResultProvider<typename DomainType::Ptr>> mResultProvider; 0120 ResultTransformation mResultTransformation; 0121 DataStoreQuery::State::Ptr mQueryState; 0122 int mBatchSize; 0123 QObject guard; 0124 Sink::Log::Context mLogCtx; 0125 bool mInitialQueryComplete = false; 0126 bool mQueryInProgress = false; 0127 bool mRequestFetchMore = false; 0128 bool mDelayNextQuery = false; 0129 bool mRevisionChangedMeanwhile = false; 0130 };