summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/domain/applicationdomaintype.h9
-rw-r--r--common/entitystorage.h3
-rw-r--r--common/resultprovider.h49
-rw-r--r--common/synclistresult.h18
-rw-r--r--tests/genericfacadetest.cpp79
5 files changed, 154 insertions, 4 deletions
diff --git a/common/domain/applicationdomaintype.h b/common/domain/applicationdomaintype.h
index e0a6de0..b583a6e 100644
--- a/common/domain/applicationdomaintype.h
+++ b/common/domain/applicationdomaintype.h
@@ -97,6 +97,15 @@ private:
97 qint64 mRevision; 97 qint64 mRevision;
98}; 98};
99 99
100/*
101 * Should this be specific to the synclistresultset, in other cases we may want to take revision and resource into account.
102 */
103inline bool operator==(const ApplicationDomainType& lhs, const ApplicationDomainType& rhs)
104{
105 return lhs.identifier() == rhs.identifier()
106 && lhs.resourceInstanceIdentifier() == rhs.resourceInstanceIdentifier();
107}
108
100struct Event : public ApplicationDomainType { 109struct Event : public ApplicationDomainType {
101 typedef QSharedPointer<Event> Ptr; 110 typedef QSharedPointer<Event> Ptr;
102 using ApplicationDomainType::ApplicationDomainType; 111 using ApplicationDomainType::ApplicationDomainType;
diff --git a/common/entitystorage.h b/common/entitystorage.h
index 78dbcda..6b09cad 100644
--- a/common/entitystorage.h
+++ b/common/entitystorage.h
@@ -118,10 +118,11 @@ public:
118 break; 118 break;
119 case Akonadi2::Operation_Modification: 119 case Akonadi2::Operation_Modification:
120 Trace() << "Got modification"; 120 Trace() << "Got modification";
121 resultProvider->add(copy(*value).template staticCast<DomainType>()); 121 resultProvider->modify(copy(*value).template staticCast<DomainType>());
122 break; 122 break;
123 case Akonadi2::Operation_Removal: 123 case Akonadi2::Operation_Removal:
124 Trace() << "Got removal"; 124 Trace() << "Got removal";
125 resultProvider->remove(copy(*value).template staticCast<DomainType>());
125 break; 126 break;
126 } 127 }
127 return true; 128 return true;
diff --git a/common/resultprovider.h b/common/resultprovider.h
index 841fd01..bc03152 100644
--- a/common/resultprovider.h
+++ b/common/resultprovider.h
@@ -81,6 +81,28 @@ public:
81 }); 81 });
82 } 82 }
83 83
84 void modify(const T &value)
85 {
86 //Because I don't know how to use bind
87 auto weakEmitter = mResultEmitter;
88 callInMainThreadOnEmitter([weakEmitter, value](){
89 if (auto strongRef = weakEmitter.toStrongRef()) {
90 strongRef->modifyHandler(value);
91 }
92 });
93 }
94
95 void remove(const T &value)
96 {
97 //Because I don't know how to use bind
98 auto weakEmitter = mResultEmitter;
99 callInMainThreadOnEmitter([weakEmitter, value](){
100 if (auto strongRef = weakEmitter.toStrongRef()) {
101 strongRef->removeHandler(value);
102 }
103 });
104 }
105
84 void initialResultSetComplete() 106 void initialResultSetComplete()
85 { 107 {
86 callInMainThreadOnEmitter(&ResultEmitter<T>::initialResultSetComplete); 108 callInMainThreadOnEmitter(&ResultEmitter<T>::initialResultSetComplete);
@@ -176,15 +198,27 @@ public:
176 { 198 {
177 addHandler = handler; 199 addHandler = handler;
178 } 200 }
179 // void onRemoved(const std::function<void(const T&)> &handler); 201
202 void onModified(const std::function<void(const DomainType&)> &handler)
203 {
204 modifyHandler = handler;
205 }
206
207 void onRemoved(const std::function<void(const DomainType&)> &handler)
208 {
209 removeHandler = handler;
210 }
211
180 void onInitialResultSetComplete(const std::function<void(void)> &handler) 212 void onInitialResultSetComplete(const std::function<void(void)> &handler)
181 { 213 {
182 initialResultSetCompleteHandler = handler; 214 initialResultSetCompleteHandler = handler;
183 } 215 }
216
184 void onComplete(const std::function<void(void)> &handler) 217 void onComplete(const std::function<void(void)> &handler)
185 { 218 {
186 completeHandler = handler; 219 completeHandler = handler;
187 } 220 }
221
188 void onClear(const std::function<void(void)> &handler) 222 void onClear(const std::function<void(void)> &handler)
189 { 223 {
190 clearHandler = handler; 224 clearHandler = handler;
@@ -195,6 +229,16 @@ public:
195 addHandler(value); 229 addHandler(value);
196 } 230 }
197 231
232 void modify(const DomainType &value)
233 {
234 modifyHandler(value);
235 }
236
237 void remove(const DomainType &value)
238 {
239 removeHandler(value);
240 }
241
198 void initialResultSetComplete() 242 void initialResultSetComplete()
199 { 243 {
200 initialResultSetCompleteHandler(); 244 initialResultSetCompleteHandler();
@@ -214,7 +258,8 @@ private:
214 friend class ResultProvider<DomainType>; 258 friend class ResultProvider<DomainType>;
215 259
216 std::function<void(const DomainType&)> addHandler; 260 std::function<void(const DomainType&)> addHandler;
217 // std::function<void(const T&)> removeHandler; 261 std::function<void(const DomainType&)> modifyHandler;
262 std::function<void(const DomainType&)> removeHandler;
218 std::function<void(void)> initialResultSetCompleteHandler; 263 std::function<void(void)> initialResultSetCompleteHandler;
219 std::function<void(void)> completeHandler; 264 std::function<void(void)> completeHandler;
220 std::function<void(void)> clearHandler; 265 std::function<void(void)> clearHandler;
diff --git a/common/synclistresult.h b/common/synclistresult.h
index 865d3e0..3ae2bed 100644
--- a/common/synclistresult.h
+++ b/common/synclistresult.h
@@ -4,6 +4,7 @@
4#include <functional> 4#include <functional>
5#include <QSharedPointer> 5#include <QSharedPointer>
6#include <QEventLoop> 6#include <QEventLoop>
7#include <QDebug>
7#include "resultprovider.h" 8#include "resultprovider.h"
8 9
9namespace async { 10namespace async {
@@ -25,6 +26,23 @@ public:
25 emitter->onAdded([this](const T &value) { 26 emitter->onAdded([this](const T &value) {
26 this->append(value); 27 this->append(value);
27 }); 28 });
29 emitter->onModified([this](const T &value) {
30 for (auto it = this->begin(); it != this->end(); it++) {
31 if (**it == *value) {
32 it = this->erase(it);
33 this->insert(it, value);
34 break;
35 }
36 }
37 });
38 emitter->onRemoved([this](const T &value) {
39 for (auto it = this->begin(); it != this->end(); it++) {
40 if (**it == *value) {
41 this->erase(it);
42 break;
43 }
44 }
45 });
28 emitter->onInitialResultSetComplete([this]() { 46 emitter->onInitialResultSetComplete([this]() {
29 if (eventLoopAborter) { 47 if (eventLoopAborter) {
30 eventLoopAborter(); 48 eventLoopAborter();
diff --git a/tests/genericfacadetest.cpp b/tests/genericfacadetest.cpp
index f21de70..e9c1a94 100644
--- a/tests/genericfacadetest.cpp
+++ b/tests/genericfacadetest.cpp
@@ -30,10 +30,18 @@ public:
30 for (const auto &res : mResults) { 30 for (const auto &res : mResults) {
31 resultProvider->add(res); 31 resultProvider->add(res);
32 } 32 }
33 for (const auto &res : mModifications) {
34 resultProvider->modify(res);
35 }
36 for (const auto &res : mRemovals) {
37 resultProvider->remove(res);
38 }
33 return mLatestRevision; 39 return mLatestRevision;
34 } 40 }
35 41
36 QList<Akonadi2::ApplicationDomain::Event::Ptr> mResults; 42 QList<Akonadi2::ApplicationDomain::Event::Ptr> mResults;
43 QList<Akonadi2::ApplicationDomain::Event::Ptr> mModifications;
44 QList<Akonadi2::ApplicationDomain::Event::Ptr> mRemovals;
37 qint64 mLatestRevision; 45 qint64 mLatestRevision;
38}; 46};
39 47
@@ -126,9 +134,78 @@ private Q_SLOTS:
126 resultSet->initialResultSetComplete(); 134 resultSet->initialResultSetComplete();
127 result.exec(); 135 result.exec();
128 136
129 // QTRY_COMPARE(result.size(), 2);
130 QCOMPARE(result.size(), 2); 137 QCOMPARE(result.size(), 2);
131 } 138 }
139
140 void testLiveQueryModify()
141 {
142 Akonadi2::Query query;
143 query.liveQuery = true;
144
145 auto resultSet = QSharedPointer<Akonadi2::ResultProvider<Akonadi2::ApplicationDomain::Event::Ptr> >::create();
146 auto storage = QSharedPointer<TestEntityStorage>::create("identifier", QSharedPointer<TestEventAdaptorFactory>::create(), "bufferType");
147 auto resourceAccess = QSharedPointer<TestResourceAccess>::create();
148 auto entity = QSharedPointer<Akonadi2::ApplicationDomain::Event>::create("resource", "id2", 0, QSharedPointer<Akonadi2::ApplicationDomain::MemoryBufferAdaptor>::create());
149 entity->setProperty("test", "test1");
150 storage->mResults << entity;
151 TestResourceFacade facade("identifier", storage, resourceAccess);
152
153 async::SyncListResult<Akonadi2::ApplicationDomain::Event::Ptr> result(resultSet->emitter());
154
155 facade.load(query, resultSet).exec().waitForFinished();
156 resultSet->initialResultSetComplete();
157
158 result.exec();
159 QCOMPARE(result.size(), 1);
160
161 //Modify the entity again
162 storage->mResults.clear();
163 entity = QSharedPointer<Akonadi2::ApplicationDomain::Event>::create("resource", "id2", 0, QSharedPointer<Akonadi2::ApplicationDomain::MemoryBufferAdaptor>::create());
164 entity->setProperty("test", "test2");
165 storage->mModifications << entity;
166 storage->mLatestRevision = 2;
167 resourceAccess->emit revisionChanged(2);
168
169 //Hack to get event loop in synclistresult to abort again
170 resultSet->initialResultSetComplete();
171 result.exec();
172
173 QCOMPARE(result.size(), 1);
174 QCOMPARE(result.first()->getProperty("test").toByteArray(), QByteArray("test2"));
175 }
176
177 void testLiveQueryRemove()
178 {
179 Akonadi2::Query query;
180 query.liveQuery = true;
181
182 auto resultSet = QSharedPointer<Akonadi2::ResultProvider<Akonadi2::ApplicationDomain::Event::Ptr> >::create();
183 auto storage = QSharedPointer<TestEntityStorage>::create("identifier", QSharedPointer<TestEventAdaptorFactory>::create(), "bufferType");
184 auto resourceAccess = QSharedPointer<TestResourceAccess>::create();
185 auto entity = QSharedPointer<Akonadi2::ApplicationDomain::Event>::create("resource", "id2", 0, QSharedPointer<Akonadi2::ApplicationDomain::BufferAdaptor>());
186 storage->mResults << entity;
187 TestResourceFacade facade("identifier", storage, resourceAccess);
188
189 async::SyncListResult<Akonadi2::ApplicationDomain::Event::Ptr> result(resultSet->emitter());
190
191 facade.load(query, resultSet).exec().waitForFinished();
192 resultSet->initialResultSetComplete();
193
194 result.exec();
195 QCOMPARE(result.size(), 1);
196
197 //Remove the entity again
198 storage->mResults.clear();
199 storage->mRemovals << entity;
200 storage->mLatestRevision = 2;
201 resourceAccess->emit revisionChanged(2);
202
203 //Hack to get event loop in synclistresult to abort again
204 resultSet->initialResultSetComplete();
205 result.exec();
206
207 QCOMPARE(result.size(), 0);
208 }
132}; 209};
133 210
134QTEST_MAIN(GenericFacadeTest) 211QTEST_MAIN(GenericFacadeTest)