diff options
-rw-r--r-- | common/clientapi.cpp | 12 | ||||
-rw-r--r-- | common/clientapi.h | 12 | ||||
-rw-r--r-- | common/modelresult.cpp | 2 | ||||
-rw-r--r-- | common/queryrunner.cpp | 24 | ||||
-rw-r--r-- | common/queryrunner.h | 1 | ||||
-rw-r--r-- | common/resultprovider.h | 2 | ||||
-rw-r--r-- | examples/client/main.cpp | 4 | ||||
-rw-r--r-- | examples/dummyresource/dummystore.cpp | 2 |
8 files changed, 26 insertions, 33 deletions
diff --git a/common/clientapi.cpp b/common/clientapi.cpp index b24dfa8..29b7e68 100644 --- a/common/clientapi.cpp +++ b/common/clientapi.cpp | |||
@@ -41,7 +41,7 @@ | |||
41 | 41 | ||
42 | namespace async | 42 | namespace async |
43 | { | 43 | { |
44 | void run(const std::function<void()> &runner) { | 44 | static void run(const std::function<void()> &runner) { |
45 | auto timer = new QTimer(); | 45 | auto timer = new QTimer(); |
46 | timer->setSingleShot(true); | 46 | timer->setSingleShot(true); |
47 | QObject::connect(timer, &QTimer::timeout, [runner, timer]() { | 47 | QObject::connect(timer, &QTimer::timeout, [runner, timer]() { |
@@ -98,15 +98,6 @@ QList<QByteArray> Store::getResources(const QList<QByteArray> &resourceFilter, c | |||
98 | } | 98 | } |
99 | 99 | ||
100 | template <class DomainType> | 100 | template <class DomainType> |
101 | QSharedPointer<ResultEmitter<typename DomainType::Ptr> > Store::load(Query query) | ||
102 | { | ||
103 | auto resultSet = QSharedPointer<ResultProvider<typename DomainType::Ptr> >::create(); | ||
104 | qWarning() << "Main thread " << QThread::currentThreadId(); | ||
105 | //FIXME remove | ||
106 | return resultSet->emitter(); | ||
107 | } | ||
108 | |||
109 | template <class DomainType> | ||
110 | QSharedPointer<QAbstractItemModel> Store::loadModel(Query query) | 101 | QSharedPointer<QAbstractItemModel> Store::loadModel(Query query) |
111 | { | 102 | { |
112 | auto model = QSharedPointer<ModelResult<DomainType, typename DomainType::Ptr> >::create(query, query.requestedProperties.toList()); | 103 | auto model = QSharedPointer<ModelResult<DomainType, typename DomainType::Ptr> >::create(query, query.requestedProperties.toList()); |
@@ -213,7 +204,6 @@ KAsync::Job<void> Store::synchronize(const Akonadi2::Query &query) | |||
213 | #define REGISTER_TYPE(T) template KAsync::Job<void> Store::remove<T>(const T &domainObject); \ | 204 | #define REGISTER_TYPE(T) template KAsync::Job<void> Store::remove<T>(const T &domainObject); \ |
214 | template KAsync::Job<void> Store::create<T>(const T &domainObject); \ | 205 | template KAsync::Job<void> Store::create<T>(const T &domainObject); \ |
215 | template KAsync::Job<void> Store::modify<T>(const T &domainObject); \ | 206 | template KAsync::Job<void> Store::modify<T>(const T &domainObject); \ |
216 | template QSharedPointer<ResultEmitter<typename T::Ptr> > Store::load<T>(Query query); \ | ||
217 | template QSharedPointer<QAbstractItemModel> Store::loadModel<T>(Query query); \ | 207 | template QSharedPointer<QAbstractItemModel> Store::loadModel<T>(Query query); \ |
218 | 208 | ||
219 | REGISTER_TYPE(ApplicationDomain::Event); | 209 | REGISTER_TYPE(ApplicationDomain::Event); |
diff --git a/common/clientapi.h b/common/clientapi.h index c48c6e9..7fee6ae 100644 --- a/common/clientapi.h +++ b/common/clientapi.h | |||
@@ -33,12 +33,6 @@ Q_DECLARE_METATYPE(std::shared_ptr<void>); | |||
33 | 33 | ||
34 | class QAbstractItemModel; | 34 | class QAbstractItemModel; |
35 | 35 | ||
36 | namespace async { | ||
37 | //This should abstract if we execute from eventloop or in thread. | ||
38 | //It supposed to allow the caller to finish the current method before executing the runner. | ||
39 | void run(const std::function<void()> &runner); | ||
40 | } | ||
41 | |||
42 | namespace Akonadi2 { | 36 | namespace Akonadi2 { |
43 | 37 | ||
44 | using namespace async; | 38 | using namespace async; |
@@ -54,12 +48,6 @@ public: | |||
54 | static QString storageLocation(); | 48 | static QString storageLocation(); |
55 | static QByteArray resourceName(const QByteArray &instanceIdentifier); | 49 | static QByteArray resourceName(const QByteArray &instanceIdentifier); |
56 | 50 | ||
57 | /** | ||
58 | * Asynchronusly load a dataset | ||
59 | */ | ||
60 | template <class DomainType> | ||
61 | static QSharedPointer<ResultEmitter<typename DomainType::Ptr> > load(Query query); | ||
62 | |||
63 | enum Roles { | 51 | enum Roles { |
64 | DomainObjectRole = Qt::UserRole + 1 //Must be the same as in ModelResult | 52 | DomainObjectRole = Qt::UserRole + 1 //Must be the same as in ModelResult |
65 | }; | 53 | }; |
diff --git a/common/modelresult.cpp b/common/modelresult.cpp index 65eaba9..930048f 100644 --- a/common/modelresult.cpp +++ b/common/modelresult.cpp | |||
@@ -141,7 +141,7 @@ void ModelResult<T, Ptr>::add(const Ptr &value) | |||
141 | return; | 141 | return; |
142 | } | 142 | } |
143 | // qDebug() << "Inserting rows " << index << parent; | 143 | // qDebug() << "Inserting rows " << index << parent; |
144 | beginInsertRows(QModelIndex(), index, index); | 144 | beginInsertRows(parent, index, index); |
145 | mEntities.insert(childId, value); | 145 | mEntities.insert(childId, value); |
146 | mTree[id].insert(index, childId); | 146 | mTree[id].insert(index, childId); |
147 | mParents.insert(childId, id); | 147 | mParents.insert(childId, id); |
diff --git a/common/queryrunner.cpp b/common/queryrunner.cpp index 4159112..3f62f6a 100644 --- a/common/queryrunner.cpp +++ b/common/queryrunner.cpp | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <QtConcurrent/QtConcurrentRun> | 21 | #include <QtConcurrent/QtConcurrentRun> |
22 | #include <QFuture> | 22 | #include <QFuture> |
23 | #include <QFutureWatcher> | 23 | #include <QFutureWatcher> |
24 | #include <QTime> | ||
24 | #include "commands.h" | 25 | #include "commands.h" |
25 | #include "log.h" | 26 | #include "log.h" |
26 | #include "storage.h" | 27 | #include "storage.h" |
@@ -45,7 +46,7 @@ static inline ResultSet fullScan(const Akonadi2::Storage::Transaction &transacti | |||
45 | qWarning() << "Error during query: " << error.message; | 46 | qWarning() << "Error during query: " << error.message; |
46 | }); | 47 | }); |
47 | 48 | ||
48 | Trace() << "Full scan found " << keys.size() << " results"; | 49 | Trace() << "Full scan on " << bufferType << " found " << keys.size() << " results"; |
49 | return ResultSet(keys); | 50 | return ResultSet(keys); |
50 | } | 51 | } |
51 | 52 | ||
@@ -97,6 +98,12 @@ QueryRunner<DomainType>::QueryRunner(const Akonadi2::Query &query, const Akonadi | |||
97 | } | 98 | } |
98 | 99 | ||
99 | template<class DomainType> | 100 | template<class DomainType> |
101 | QueryRunner<DomainType>::~QueryRunner() | ||
102 | { | ||
103 | Trace() << "Stopped query"; | ||
104 | } | ||
105 | |||
106 | template<class DomainType> | ||
100 | typename Akonadi2::ResultEmitter<typename DomainType::Ptr>::Ptr QueryRunner<DomainType>::emitter() | 107 | typename Akonadi2::ResultEmitter<typename DomainType::Ptr>::Ptr QueryRunner<DomainType>::emitter() |
101 | { | 108 | { |
102 | return mResultProvider->emitter(); | 109 | return mResultProvider->emitter(); |
@@ -202,7 +209,6 @@ ResultSet QueryRunner<DomainType>::filterSet(const ResultSet &resultSet, const s | |||
202 | readEntity(db, resultSetPtr->id(), [this, filter, callback, initialQuery](const Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr &domainObject, Akonadi2::Operation operation) { | 209 | readEntity(db, resultSetPtr->id(), [this, filter, callback, initialQuery](const Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr &domainObject, Akonadi2::Operation operation) { |
203 | //Always remove removals, they probably don't match due to non-available properties | 210 | //Always remove removals, they probably don't match due to non-available properties |
204 | if (filter(domainObject) || operation == Akonadi2::Operation_Removal) { | 211 | if (filter(domainObject) || operation == Akonadi2::Operation_Removal) { |
205 | Trace() << "entity is not filtered" << initialQuery; | ||
206 | if (initialQuery) { | 212 | if (initialQuery) { |
207 | //We're not interested in removals during the initial query | 213 | //We're not interested in removals during the initial query |
208 | if (operation != Akonadi2::Operation_Removal) { | 214 | if (operation != Akonadi2::Operation_Removal) { |
@@ -262,16 +268,24 @@ qint64 QueryRunner<DomainType>::load(const Akonadi2::Query &query, const std::fu | |||
262 | template<class DomainType> | 268 | template<class DomainType> |
263 | qint64 QueryRunner<DomainType>::executeIncrementalQuery(const Akonadi2::Query &query, Akonadi2::ResultProviderInterface<typename DomainType::Ptr> &resultProvider) | 269 | qint64 QueryRunner<DomainType>::executeIncrementalQuery(const Akonadi2::Query &query, Akonadi2::ResultProviderInterface<typename DomainType::Ptr> &resultProvider) |
264 | { | 270 | { |
271 | QTime time; | ||
272 | time.start(); | ||
273 | |||
265 | const qint64 baseRevision = resultProvider.revision() + 1; | 274 | const qint64 baseRevision = resultProvider.revision() + 1; |
266 | Trace() << "Running incremental query " << baseRevision; | 275 | Trace() << "Running incremental query " << baseRevision; |
267 | return load(query, [&](Akonadi2::Storage::Transaction &transaction, QSet<QByteArray> &remainingFilters) -> ResultSet { | 276 | auto revision = load(query, [&](Akonadi2::Storage::Transaction &transaction, QSet<QByteArray> &remainingFilters) -> ResultSet { |
268 | return loadIncrementalResultSet(baseRevision, query, transaction, remainingFilters); | 277 | return loadIncrementalResultSet(baseRevision, query, transaction, remainingFilters); |
269 | }, resultProvider, false); | 278 | }, resultProvider, false); |
279 | Trace() << "Incremental query took: " << time.elapsed() << " ms"; | ||
280 | return revision; | ||
270 | } | 281 | } |
271 | 282 | ||
272 | template<class DomainType> | 283 | template<class DomainType> |
273 | qint64 QueryRunner<DomainType>::executeInitialQuery(const Akonadi2::Query &query, const typename DomainType::Ptr &parent, Akonadi2::ResultProviderInterface<typename DomainType::Ptr> &resultProvider) | 284 | qint64 QueryRunner<DomainType>::executeInitialQuery(const Akonadi2::Query &query, const typename DomainType::Ptr &parent, Akonadi2::ResultProviderInterface<typename DomainType::Ptr> &resultProvider) |
274 | { | 285 | { |
286 | QTime time; | ||
287 | time.start(); | ||
288 | |||
275 | auto modifiedQuery = query; | 289 | auto modifiedQuery = query; |
276 | if (!query.parentProperty.isEmpty()) { | 290 | if (!query.parentProperty.isEmpty()) { |
277 | if (parent) { | 291 | if (parent) { |
@@ -282,9 +296,11 @@ qint64 QueryRunner<DomainType>::executeInitialQuery(const Akonadi2::Query &query | |||
282 | modifiedQuery.propertyFilter.insert(query.parentProperty, QVariant()); | 296 | modifiedQuery.propertyFilter.insert(query.parentProperty, QVariant()); |
283 | } | 297 | } |
284 | } | 298 | } |
285 | return load(modifiedQuery, [&](Akonadi2::Storage::Transaction &transaction, QSet<QByteArray> &remainingFilters) -> ResultSet { | 299 | auto revision = load(modifiedQuery, [&](Akonadi2::Storage::Transaction &transaction, QSet<QByteArray> &remainingFilters) -> ResultSet { |
286 | return loadInitialResultSet(modifiedQuery, transaction, remainingFilters); | 300 | return loadInitialResultSet(modifiedQuery, transaction, remainingFilters); |
287 | }, resultProvider, true); | 301 | }, resultProvider, true); |
302 | Trace() << "Initial query took: " << time.elapsed() << " ms"; | ||
303 | return revision; | ||
288 | } | 304 | } |
289 | 305 | ||
290 | template class QueryRunner<Akonadi2::ApplicationDomain::Folder>; | 306 | template class QueryRunner<Akonadi2::ApplicationDomain::Folder>; |
diff --git a/common/queryrunner.h b/common/queryrunner.h index e2af9de..c918dcb 100644 --- a/common/queryrunner.h +++ b/common/queryrunner.h | |||
@@ -79,6 +79,7 @@ class QueryRunner : public QueryRunnerBase | |||
79 | { | 79 | { |
80 | public: | 80 | public: |
81 | QueryRunner(const Akonadi2::Query &query, const Akonadi2::ResourceAccessInterface::Ptr &, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &, const QByteArray &bufferType); | 81 | QueryRunner(const Akonadi2::Query &query, const Akonadi2::ResourceAccessInterface::Ptr &, const QByteArray &instanceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &, const QByteArray &bufferType); |
82 | virtual ~QueryRunner(); | ||
82 | 83 | ||
83 | typename Akonadi2::ResultEmitter<typename DomainType::Ptr>::Ptr emitter(); | 84 | typename Akonadi2::ResultEmitter<typename DomainType::Ptr>::Ptr emitter(); |
84 | 85 | ||
diff --git a/common/resultprovider.h b/common/resultprovider.h index 86382ef..6d7867a 100644 --- a/common/resultprovider.h +++ b/common/resultprovider.h | |||
@@ -106,7 +106,7 @@ private: | |||
106 | public: | 106 | public: |
107 | typedef QSharedPointer<ResultProvider<T> > Ptr; | 107 | typedef QSharedPointer<ResultProvider<T> > Ptr; |
108 | 108 | ||
109 | ~ResultProvider() | 109 | virtual ~ResultProvider() |
110 | { | 110 | { |
111 | } | 111 | } |
112 | 112 | ||
diff --git a/examples/client/main.cpp b/examples/client/main.cpp index c75b3ce..3fa5a4e 100644 --- a/examples/client/main.cpp +++ b/examples/client/main.cpp | |||
@@ -77,7 +77,6 @@ public: | |||
77 | topLayout->addWidget(titleLabel); | 77 | topLayout->addWidget(titleLabel); |
78 | topLayout->addWidget(syncButton); | 78 | topLayout->addWidget(syncButton); |
79 | topLayout->addWidget(modelView, 10); | 79 | topLayout->addWidget(modelView, 10); |
80 | model->fetchMore(QModelIndex()); | ||
81 | 80 | ||
82 | show(); | 81 | show(); |
83 | } | 82 | } |
@@ -127,6 +126,7 @@ int main(int argc, char *argv[]) | |||
127 | query.syncOnDemand = false; | 126 | query.syncOnDemand = false; |
128 | query.processAll = false; | 127 | query.processAll = false; |
129 | query.requestedProperties << "name"; | 128 | query.requestedProperties << "name"; |
129 | query.liveQuery = true; | ||
130 | 130 | ||
131 | auto model = Akonadi2::Store::loadModel<Akonadi2::ApplicationDomain::Folder>(query); | 131 | auto model = Akonadi2::Store::loadModel<Akonadi2::ApplicationDomain::Folder>(query); |
132 | if (cliOptions.isSet("list")) { | 132 | if (cliOptions.isSet("list")) { |
@@ -137,11 +137,9 @@ int main(int argc, char *argv[]) | |||
137 | qDebug() << model->data(model->index(i, 0, index)).toString(); | 137 | qDebug() << model->data(model->index(i, 0, index)).toString(); |
138 | } | 138 | } |
139 | }); | 139 | }); |
140 | model->fetchMore(QModelIndex()); | ||
141 | return app.exec(); | 140 | return app.exec(); |
142 | } else if (cliOptions.isSet("count")) { | 141 | } else if (cliOptions.isSet("count")) { |
143 | query.liveQuery = false; | 142 | query.liveQuery = false; |
144 | model->fetchMore(QModelIndex()); | ||
145 | qDebug() << "Counted results " << model->rowCount(QModelIndex()); | 143 | qDebug() << "Counted results " << model->rowCount(QModelIndex()); |
146 | } else { | 144 | } else { |
147 | query.liveQuery = true; | 145 | query.liveQuery = true; |
diff --git a/examples/dummyresource/dummystore.cpp b/examples/dummyresource/dummystore.cpp index 39ecfe4..458695f 100644 --- a/examples/dummyresource/dummystore.cpp +++ b/examples/dummyresource/dummystore.cpp | |||
@@ -64,7 +64,7 @@ QMap<QString, QMap<QString, QVariant> > populateMails() | |||
64 | QMap<QString, QMap<QString, QVariant> > populateFolders() | 64 | QMap<QString, QMap<QString, QVariant> > populateFolders() |
65 | { | 65 | { |
66 | QMap<QString, QMap<QString, QVariant>> content; | 66 | QMap<QString, QMap<QString, QVariant>> content; |
67 | for (int i = 0; i < 5000; i++) { | 67 | for (int i = 0; i < 5; i++) { |
68 | content.insert(QString("key%1").arg(i), createFolder(i)); | 68 | content.insert(QString("key%1").arg(i), createFolder(i)); |
69 | } | 69 | } |
70 | return content; | 70 | return content; |