summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/CMakeLists.txt1
-rw-r--r--common/clientapi.cpp8
-rw-r--r--common/clientapi.h97
-rw-r--r--common/domain/event.fbs2
-rw-r--r--common/domainadaptor.cpp63
-rw-r--r--common/domainadaptor.h187
-rw-r--r--common/entitybuffer.cpp27
-rw-r--r--common/entitybuffer.h26
-rw-r--r--common/facade.h88
-rw-r--r--common/resource.h7
-rw-r--r--common/resourceaccess.cpp10
-rw-r--r--common/resourceaccess.h4
-rw-r--r--common/storage.h2
-rw-r--r--common/storage_common.cpp2
-rw-r--r--common/storage_lmdb.cpp4
-rw-r--r--common/test/clientapitest.cpp18
16 files changed, 438 insertions, 108 deletions
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index 650691c..b06718f 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -30,6 +30,7 @@ set(command_SRCS
30 commands.cpp 30 commands.cpp
31 console.cpp 31 console.cpp
32 pipeline.cpp 32 pipeline.cpp
33 domainadaptor.cpp
33 resource.cpp 34 resource.cpp
34 resourceaccess.cpp 35 resourceaccess.cpp
35 storage_common.cpp 36 storage_common.cpp
diff --git a/common/clientapi.cpp b/common/clientapi.cpp
index 6f0b421..48de1b0 100644
--- a/common/clientapi.cpp
+++ b/common/clientapi.cpp
@@ -14,24 +14,24 @@ namespace async
14namespace Akonadi2 14namespace Akonadi2
15{ 15{
16 16
17namespace Domain 17namespace ApplicationDomain
18{ 18{
19 19
20template<> 20template<>
21QString getTypeName<Event>() 21QByteArray getTypeName<Event>()
22{ 22{
23 return "event"; 23 return "event";
24} 24}
25 25
26template<> 26template<>
27QString getTypeName<Todo>() 27QByteArray getTypeName<Todo>()
28{ 28{
29 return "todo"; 29 return "todo";
30} 30}
31 31
32} // namespace Domain 32} // namespace Domain
33 33
34void Store::shutdown(const QString &identifier) 34void Store::shutdown(const QByteArray &identifier)
35{ 35{
36 Akonadi2::ResourceAccess resourceAccess(identifier); 36 Akonadi2::ResourceAccess resourceAccess(identifier);
37 //FIXME this starts the resource, just to shut it down again if it's not running in the first place. 37 //FIXME this starts the resource, just to shut it down again if it's not running in the first place.
diff --git a/common/clientapi.h b/common/clientapi.h
index 63305ab..22448b3 100644
--- a/common/clientapi.h
+++ b/common/clientapi.h
@@ -163,7 +163,7 @@ namespace async {
163namespace Akonadi2 { 163namespace Akonadi2 {
164 164
165/** 165/**
166 * Standardized Domain Types 166 * Standardized Application Domain Types
167 * 167 *
168 * They don't adhere to any standard and can be freely extended 168 * They don't adhere to any standard and can be freely extended
169 * Their sole purpose is providing a standardized interface to access data. 169 * Their sole purpose is providing a standardized interface to access data.
@@ -172,7 +172,7 @@ namespace Akonadi2 {
172 * 172 *
173 * These types will be frequently modified (for every new feature that should be exposed to the any client) 173 * These types will be frequently modified (for every new feature that should be exposed to the any client)
174 */ 174 */
175namespace Domain { 175namespace ApplicationDomain {
176 176
177/** 177/**
178 * This class has to be implemented by resources and can be used as generic interface to access the buffer properties 178 * This class has to be implemented by resources and can be used as generic interface to access the buffer properties
@@ -180,9 +180,9 @@ namespace Domain {
180class BufferAdaptor { 180class BufferAdaptor {
181public: 181public:
182 virtual ~BufferAdaptor() {} 182 virtual ~BufferAdaptor() {}
183 virtual QVariant getProperty(const QString &key) const { return QVariant(); } 183 virtual QVariant getProperty(const QByteArray &key) const { return QVariant(); }
184 virtual void setProperty(const QString &key, const QVariant &value) {} 184 virtual void setProperty(const QByteArray &key, const QVariant &value) {}
185 virtual QStringList availableProperties() const { return QStringList(); } 185 virtual QList<QByteArray> availableProperties() const { return QList<QByteArray>(); }
186}; 186};
187 187
188class MemoryBufferAdaptor : public BufferAdaptor { 188class MemoryBufferAdaptor : public BufferAdaptor {
@@ -202,12 +202,12 @@ public:
202 202
203 virtual ~MemoryBufferAdaptor() {} 203 virtual ~MemoryBufferAdaptor() {}
204 204
205 virtual QVariant getProperty(const QString &key) const { return mValues.value(key); } 205 virtual QVariant getProperty(const QByteArray &key) const { return mValues.value(key); }
206 virtual void setProperty(const QString &key, const QVariant &value) { mValues.insert(key, value); } 206 virtual void setProperty(const QByteArray &key, const QVariant &value) { mValues.insert(key, value); }
207 virtual QStringList availableProperties() const { return mValues.keys(); } 207 virtual QByteArrayList availableProperties() const { return mValues.keys(); }
208 208
209private: 209private:
210 QHash<QString, QVariant> mValues; 210 QHash<QByteArray, QVariant> mValues;
211}; 211};
212 212
213/** 213/**
@@ -215,14 +215,14 @@ private:
215 * * provide a unified interface to read buffers (for zero-copy reading) 215 * * provide a unified interface to read buffers (for zero-copy reading)
216 * * record changes to generate changesets for modifications 216 * * record changes to generate changesets for modifications
217 */ 217 */
218class AkonadiDomainType { 218class ApplicationDomainType {
219public: 219public:
220 AkonadiDomainType() 220 ApplicationDomainType()
221 :mAdaptor(new MemoryBufferAdaptor()) 221 :mAdaptor(new MemoryBufferAdaptor())
222 { 222 {
223 223
224 } 224 }
225 AkonadiDomainType(const QString &resourceName, const QString &identifier, qint64 revision, const QSharedPointer<BufferAdaptor> &adaptor) 225 ApplicationDomainType(const QByteArray &resourceName, const QByteArray &identifier, qint64 revision, const QSharedPointer<BufferAdaptor> &adaptor)
226 : mAdaptor(adaptor), 226 : mAdaptor(adaptor),
227 mResourceName(resourceName), 227 mResourceName(resourceName),
228 mIdentifier(identifier), 228 mIdentifier(identifier),
@@ -230,41 +230,43 @@ public:
230 { 230 {
231 } 231 }
232 232
233 virtual ~AkonadiDomainType() {} 233 virtual ~ApplicationDomainType() {}
234 234
235 virtual QVariant getProperty(const QString &key) const { return mAdaptor->getProperty(key); } 235 virtual QVariant getProperty(const QByteArray &key) const { return mAdaptor->getProperty(key); }
236 virtual void setProperty(const QString &key, const QVariant &value){ mChangeSet.insert(key, value); mAdaptor->setProperty(key, value); } 236 virtual void setProperty(const QByteArray &key, const QVariant &value){ mChangeSet.insert(key, value); mAdaptor->setProperty(key, value); }
237 virtual QByteArrayList changedProperties() const { return mChangeSet.keys(); }
238 qint64 revision() const { return mRevision; }
237 239
238private: 240private:
239 QSharedPointer<BufferAdaptor> mAdaptor; 241 QSharedPointer<BufferAdaptor> mAdaptor;
240 QHash<QString, QVariant> mChangeSet; 242 QHash<QByteArray, QVariant> mChangeSet;
241 /* 243 /*
242 * Each domain object needs to store the resource, identifier, revision triple so we can link back to the storage location. 244 * Each domain object needs to store the resource, identifier, revision triple so we can link back to the storage location.
243 */ 245 */
244 QString mResourceName; 246 QString mResourceName;
245 QString mIdentifier; 247 QByteArray mIdentifier;
246 qint64 mRevision; 248 qint64 mRevision;
247}; 249};
248 250
249struct Event : public AkonadiDomainType { 251struct Event : public ApplicationDomainType {
250 typedef QSharedPointer<Event> Ptr; 252 typedef QSharedPointer<Event> Ptr;
251 using AkonadiDomainType::AkonadiDomainType; 253 using ApplicationDomainType::ApplicationDomainType;
252}; 254};
253 255
254struct Todo : public AkonadiDomainType { 256struct Todo : public ApplicationDomainType {
255 typedef QSharedPointer<Todo> Ptr; 257 typedef QSharedPointer<Todo> Ptr;
256 using AkonadiDomainType::AkonadiDomainType; 258 using ApplicationDomainType::ApplicationDomainType;
257}; 259};
258 260
259struct Calendar : public AkonadiDomainType { 261struct Calendar : public ApplicationDomainType {
260 typedef QSharedPointer<Calendar> Ptr; 262 typedef QSharedPointer<Calendar> Ptr;
261 using AkonadiDomainType::AkonadiDomainType; 263 using ApplicationDomainType::ApplicationDomainType;
262}; 264};
263 265
264class Mail : public AkonadiDomainType { 266class Mail : public ApplicationDomainType {
265}; 267};
266 268
267class Folder : public AkonadiDomainType { 269class Folder : public ApplicationDomainType {
268}; 270};
269 271
270/** 272/**
@@ -274,13 +276,13 @@ class Folder : public AkonadiDomainType {
274 */ 276 */
275 277
276template<class DomainType> 278template<class DomainType>
277QString getTypeName(); 279QByteArray getTypeName();
278 280
279template<> 281template<>
280QString getTypeName<Event>(); 282QByteArray getTypeName<Event>();
281 283
282template<> 284template<>
283QString getTypeName<Todo>(); 285QByteArray getTypeName<Todo>();
284 286
285} 287}
286 288
@@ -298,19 +300,22 @@ using namespace async;
298 * * what resources to search 300 * * what resources to search
299 * * filters on various properties (parent collection, startDate range, ....) 301 * * filters on various properties (parent collection, startDate range, ....)
300 * * properties we need (for on-demand querying) 302 * * properties we need (for on-demand querying)
303 *
304 * syncOnDemand: Execute a source sync before executing the query
305 * processAll: Ensure all local messages are processed before querying to guarantee an up-to date dataset.
301 */ 306 */
302class Query 307class Query
303{ 308{
304public: 309public:
305 Query() : syncOnDemand(true), processAll(false) {} 310 Query() : syncOnDemand(true), processAll(false) {}
306 //Could also be a propertyFilter 311 //Could also be a propertyFilter
307 QStringList resources; 312 QByteArrayList resources;
308 //Could also be a propertyFilter 313 //Could also be a propertyFilter
309 QStringList ids; 314 QByteArrayList ids;
310 //Filters to apply 315 //Filters to apply
311 QHash<QString, QVariant> propertyFilter; 316 QHash<QByteArray, QVariant> propertyFilter;
312 //Properties to retrieve 317 //Properties to retrieve
313 QSet<QString> requestedProperties; 318 QSet<QByteArray> requestedProperties;
314 bool syncOnDemand; 319 bool syncOnDemand;
315 bool processAll; 320 bool processAll;
316}; 321};
@@ -328,7 +333,7 @@ template<class DomainType>
328class StoreFacade { 333class StoreFacade {
329public: 334public:
330 virtual ~StoreFacade(){}; 335 virtual ~StoreFacade(){};
331 QString type() const { return Domain::getTypeName<DomainType>(); } 336 QByteArray type() const { return ApplicationDomain::getTypeName<DomainType>(); }
332 virtual Async::Job<void> create(const DomainType &domainObject) = 0; 337 virtual Async::Job<void> create(const DomainType &domainObject) = 0;
333 virtual Async::Job<void> modify(const DomainType &domainObject) = 0; 338 virtual Async::Job<void> modify(const DomainType &domainObject) = 0;
334 virtual Async::Job<void> remove(const DomainType &domainObject) = 0; 339 virtual Async::Job<void> remove(const DomainType &domainObject) = 0;
@@ -351,15 +356,15 @@ public:
351 return factory; 356 return factory;
352 } 357 }
353 358
354 static QString key(const QString &resource, const QString &type) 359 static QByteArray key(const QByteArray &resource, const QByteArray &type)
355 { 360 {
356 return resource + type; 361 return resource + type;
357 } 362 }
358 363
359 template<class DomainType, class Facade> 364 template<class DomainType, class Facade>
360 void registerFacade(const QString &resource) 365 void registerFacade(const QByteArray &resource)
361 { 366 {
362 const QString typeName = Domain::getTypeName<DomainType>(); 367 const QByteArray typeName = ApplicationDomain::getTypeName<DomainType>();
363 mFacadeRegistry.insert(key(resource, typeName), [](){ return new Facade; }); 368 mFacadeRegistry.insert(key(resource, typeName), [](){ return new Facade; });
364 } 369 }
365 370
@@ -373,16 +378,16 @@ public:
373 * FIXME the factory function should really be returning QSharedPointer<void>, which doesn't work (std::shared_pointer<void> would though). That way i.e. a test could keep the object alive until it's done. 378 * FIXME the factory function should really be returning QSharedPointer<void>, which doesn't work (std::shared_pointer<void> would though). That way i.e. a test could keep the object alive until it's done.
374 */ 379 */
375 template<class DomainType, class Facade> 380 template<class DomainType, class Facade>
376 void registerFacade(const QString &resource, const std::function<void*(void)> &customFactoryFunction) 381 void registerFacade(const QByteArray &resource, const std::function<void*(void)> &customFactoryFunction)
377 { 382 {
378 const QString typeName = Domain::getTypeName<DomainType>(); 383 const QByteArray typeName = ApplicationDomain::getTypeName<DomainType>();
379 mFacadeRegistry.insert(key(resource, typeName), customFactoryFunction); 384 mFacadeRegistry.insert(key(resource, typeName), customFactoryFunction);
380 } 385 }
381 386
382 template<class DomainType> 387 template<class DomainType>
383 QSharedPointer<StoreFacade<DomainType> > getFacade(const QString &resource) 388 QSharedPointer<StoreFacade<DomainType> > getFacade(const QByteArray &resource)
384 { 389 {
385 const QString typeName = Domain::getTypeName<DomainType>(); 390 const QByteArray typeName = ApplicationDomain::getTypeName<DomainType>();
386 auto factoryFunction = mFacadeRegistry.value(key(resource, typeName)); 391 auto factoryFunction = mFacadeRegistry.value(key(resource, typeName));
387 if (factoryFunction) { 392 if (factoryFunction) {
388 return QSharedPointer<StoreFacade<DomainType> >(static_cast<StoreFacade<DomainType>* >(factoryFunction())); 393 return QSharedPointer<StoreFacade<DomainType> >(static_cast<StoreFacade<DomainType>* >(factoryFunction()));
@@ -392,7 +397,7 @@ public:
392 } 397 }
393 398
394private: 399private:
395 QHash<QString, std::function<void*(void)> > mFacadeRegistry; 400 QHash<QByteArray, std::function<void*(void)> > mFacadeRegistry;
396}; 401};
397 402
398/** 403/**
@@ -421,7 +426,7 @@ public:
421 // query tells us in which resources we're interested 426 // query tells us in which resources we're interested
422 // TODO: queries to individual resources could be parallelized 427 // TODO: queries to individual resources could be parallelized
423 Async::Job<void> job = Async::null<void>(); 428 Async::Job<void> job = Async::null<void>();
424 for(const QString &resource : query.resources) { 429 for(const QByteArray &resource : query.resources) {
425 auto facade = FacadeFactory::instance().getFacade<DomainType>(resource); 430 auto facade = FacadeFactory::instance().getFacade<DomainType>(resource);
426 //We have to bind an instance to the function callback. Since we use a shared pointer this keeps the result provider instance (and thus also the emitter) alive. 431 //We have to bind an instance to the function callback. Since we use a shared pointer this keeps the result provider instance (and thus also the emitter) alive.
427 std::function<void(const typename DomainType::Ptr &)> addCallback = std::bind(&ResultProvider<typename DomainType::Ptr>::add, resultSet, std::placeholders::_1); 432 std::function<void(const typename DomainType::Ptr &)> addCallback = std::bind(&ResultProvider<typename DomainType::Ptr>::add, resultSet, std::placeholders::_1);
@@ -460,7 +465,7 @@ public:
460 */ 465 */
461 //TODO return job that tracks progress until resource has stored the message in it's queue? 466 //TODO return job that tracks progress until resource has stored the message in it's queue?
462 template <class DomainType> 467 template <class DomainType>
463 static void create(const DomainType &domainObject, const QString &resourceIdentifier) { 468 static void create(const DomainType &domainObject, const QByteArray &resourceIdentifier) {
464 //Potentially move to separate thread as well 469 //Potentially move to separate thread as well
465 auto facade = FacadeFactory::instance().getFacade<DomainType>(resourceIdentifier); 470 auto facade = FacadeFactory::instance().getFacade<DomainType>(resourceIdentifier);
466 auto job = facade->create(domainObject); 471 auto job = facade->create(domainObject);
@@ -475,7 +480,7 @@ public:
475 * This includes moving etc. since these are also simple settings on a property. 480 * This includes moving etc. since these are also simple settings on a property.
476 */ 481 */
477 template <class DomainType> 482 template <class DomainType>
478 static void modify(const DomainType &domainObject, const QString &resourceIdentifier) { 483 static void modify(const DomainType &domainObject, const QByteArray &resourceIdentifier) {
479 //Potentially move to separate thread as well 484 //Potentially move to separate thread as well
480 auto facade = FacadeFactory::instance().getFacade<DomainType>(resourceIdentifier); 485 auto facade = FacadeFactory::instance().getFacade<DomainType>(resourceIdentifier);
481 facade.modify(domainObject); 486 facade.modify(domainObject);
@@ -485,13 +490,13 @@ public:
485 * Remove an entity. 490 * Remove an entity.
486 */ 491 */
487 template <class DomainType> 492 template <class DomainType>
488 static void remove(const DomainType &domainObject, const QString &resourceIdentifier) { 493 static void remove(const DomainType &domainObject, const QByteArray &resourceIdentifier) {
489 //Potentially move to separate thread as well 494 //Potentially move to separate thread as well
490 auto facade = FacadeFactory::instance().getFacade<DomainType>(resourceIdentifier); 495 auto facade = FacadeFactory::instance().getFacade<DomainType>(resourceIdentifier);
491 facade.remove(domainObject); 496 facade.remove(domainObject);
492 } 497 }
493 498
494 static void shutdown(const QString &resourceIdentifier); 499 static void shutdown(const QByteArray &resourceIdentifier);
495}; 500};
496 501
497} 502}
diff --git a/common/domain/event.fbs b/common/domain/event.fbs
index 49ff270..0c6628b 100644
--- a/common/domain/event.fbs
+++ b/common/domain/event.fbs
@@ -1,4 +1,4 @@
1namespace Akonadi2.Domain.Buffer; 1namespace Akonadi2.ApplicationDomain.Buffer;
2 2
3table Event { 3table Event {
4 uid:string; 4 uid:string;
diff --git a/common/domainadaptor.cpp b/common/domainadaptor.cpp
new file mode 100644
index 0000000..aa8c3d9
--- /dev/null
+++ b/common/domainadaptor.cpp
@@ -0,0 +1,63 @@
1/*
2 * Copyright (C) 2015 Christian Mollekopf <chrigi_1@fastmail.fm>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#include "domainadaptor.h"
21
22template <>
23flatbuffers::uoffset_t extractProperty<QString>(const QVariant &property, flatbuffers::FlatBufferBuilder &fbb)
24{
25 if (property.isValid()) {
26 return fbb.CreateString(property.toString().toStdString()).o;
27 }
28 return 0;
29}
30
31template <>
32QSharedPointer<ReadPropertyMapper<Akonadi2::ApplicationDomain::Buffer::Event> > initializeReadPropertyMapper<Akonadi2::ApplicationDomain::Buffer::Event>()
33{
34 auto propertyMapper = QSharedPointer<ReadPropertyMapper<Akonadi2::ApplicationDomain::Buffer::Event> >::create();
35 propertyMapper->addMapping("summary", [](Akonadi2::ApplicationDomain::Buffer::Event const *buffer) -> QVariant {
36 if (buffer->summary()) {
37 return QString::fromStdString(buffer->summary()->c_str());
38 }
39 return QVariant();
40 });
41 propertyMapper->addMapping("uid", [](Akonadi2::ApplicationDomain::Buffer::Event const *buffer) -> QVariant {
42 if (buffer->uid()) {
43 return QString::fromStdString(buffer->uid()->c_str());
44 }
45 return QVariant();
46 });
47 return propertyMapper;
48}
49
50template <>
51QSharedPointer<WritePropertyMapper<Akonadi2::ApplicationDomain::Buffer::EventBuilder> > initializeWritePropertyMapper<Akonadi2::ApplicationDomain::Buffer::EventBuilder>()
52{
53 auto propertyMapper = QSharedPointer<WritePropertyMapper<Akonadi2::ApplicationDomain::Buffer::EventBuilder> >::create();
54 propertyMapper->addMapping("summary", [](const QVariant &value, flatbuffers::FlatBufferBuilder &fbb) -> std::function<void(Akonadi2::ApplicationDomain::Buffer::EventBuilder &)> {
55 auto offset = extractProperty<QString>(value, fbb);
56 return [offset](Akonadi2::ApplicationDomain::Buffer::EventBuilder &builder) { builder.add_summary(offset); };
57 });
58 propertyMapper->addMapping("uid", [](const QVariant &value, flatbuffers::FlatBufferBuilder &fbb) -> std::function<void(Akonadi2::ApplicationDomain::Buffer::EventBuilder &)> {
59 auto offset = extractProperty<QString>(value, fbb);
60 return [offset](Akonadi2::ApplicationDomain::Buffer::EventBuilder &builder) { builder.add_uid(offset); };
61 });
62 return propertyMapper;
63}
diff --git a/common/domainadaptor.h b/common/domainadaptor.h
index e46e893..e356692 100644
--- a/common/domainadaptor.h
+++ b/common/domainadaptor.h
@@ -21,59 +21,194 @@
21 21
22#include "entity_generated.h" 22#include "entity_generated.h"
23#include <QVariant> 23#include <QVariant>
24#include <QString> 24#include <QByteArray>
25#include <functional> 25#include <functional>
26#include "clientapi.h" //for domain parts 26#include "clientapi.h" //for domain parts
27 27
28#include "event_generated.h"
29#include "entity_generated.h"
30#include "metadata_generated.h"
31#include "entitybuffer.h"
32
28/** 33/**
29 * The property mapper holds accessor functions for all properties. 34 * The property mapper is a non-typesafe virtual dispatch.
30 * 35 *
31 * It is by default initialized with accessors that access the local-only buffer, 36 * Instead of using an interface and requring each implementation to override
32 * and resource simply have to overwrite those accessors. 37 * a virtual method per property, the property mapper can be filled with accessors
38 * that extract the properties from resource types.
33 */ 39 */
34template<typename BufferType> 40template<typename BufferType>
35class PropertyMapper 41class ReadPropertyMapper
42{
43public:
44 virtual QVariant getProperty(const QByteArray &key, BufferType const *buffer) const
45 {
46 if (mReadAccessors.contains(key)) {
47 auto accessor = mReadAccessors.value(key);
48 return accessor(buffer);
49 }
50 return QVariant();
51 }
52 bool hasMapping(const QByteArray &key) const { return mReadAccessors.contains(key); }
53 QList<QByteArray> availableProperties() const { return mReadAccessors.keys(); }
54 void addMapping(const QByteArray &property, const std::function<QVariant(BufferType const *)> &mapping) {
55 mReadAccessors.insert(property, mapping);
56 }
57private:
58 QHash<QByteArray, std::function<QVariant(BufferType const *)> > mReadAccessors;
59};
60
61template<typename BufferBuilder>
62class WritePropertyMapper
36{ 63{
37public: 64public:
38 void setProperty(const QString &key, const QVariant &value, BufferType *buffer) 65 virtual void setProperty(const QByteArray &key, const QVariant &value, QList<std::function<void(BufferBuilder &)> > &builderCalls, flatbuffers::FlatBufferBuilder &fbb) const
39 { 66 {
40 if (mWriteAccessors.contains(key)) { 67 if (mWriteAccessors.contains(key)) {
41 auto accessor = mWriteAccessors.value(key); 68 auto accessor = mWriteAccessors.value(key);
42 return accessor(value, buffer); 69 builderCalls << accessor(value, fbb);
43 } 70 }
44 } 71 }
72 bool hasMapping(const QByteArray &key) const { return mWriteAccessors.contains(key); }
73 void addMapping(const QByteArray &property, const std::function<std::function<void(BufferBuilder &)>(const QVariant &, flatbuffers::FlatBufferBuilder &)> &mapping) {
74 mWriteAccessors.insert(property, mapping);
75 }
76private:
77 QHash<QByteArray, std::function<std::function<void(BufferBuilder &)>(const QVariant &, flatbuffers::FlatBufferBuilder &)> > mWriteAccessors;
78};
79
80/**
81 * Defines how to convert qt primitives to flatbuffer ones
82 * TODO: rename to createProperty or so?
83 */
84template <class T>
85flatbuffers::uoffset_t extractProperty(const QVariant &, flatbuffers::FlatBufferBuilder &fbb);
86
87/**
88 * Create a buffer from a domain object using the provided mappings
89 */
90template <class Builder, class Buffer>
91flatbuffers::Offset<Buffer> createBufferPart(const Akonadi2::ApplicationDomain::ApplicationDomainType &domainObject, flatbuffers::FlatBufferBuilder &fbb, const WritePropertyMapper<Builder> &mapper)
92{
93 //First create a primitives such as strings using the mappings
94 QList<std::function<void(Builder &)> > propertiesToAddToResource;
95 for (const auto &property : domainObject.changedProperties()) {
96 qWarning() << "copying property " << property;
97 const auto value = domainObject.getProperty(property);
98 if (mapper.hasMapping(property)) {
99 mapper.setProperty(property, domainObject.getProperty(property), propertiesToAddToResource, fbb);
100 } else {
101 qWarning() << "no mapping for property available " << property;
102 }
103 }
104
105 //Then create all porperties using the above generated builderCalls
106 Builder builder(fbb);
107 for (auto propertyBuilder : propertiesToAddToResource) {
108 propertyBuilder(builder);
109 }
110 return builder.Finish();
111}
112
113/**
114 * A generic adaptor implementation that uses a property mapper to read/write values.
115 *
116 * TODO: this is the read-only part. Create a write only equivalent
117 */
118template <class LocalBuffer, class ResourceBuffer>
119class GenericBufferAdaptor : public Akonadi2::ApplicationDomain::BufferAdaptor
120{
121public:
122 GenericBufferAdaptor()
123 : BufferAdaptor()
124 {
125
126 }
45 127
46 virtual QVariant getProperty(const QString &key, BufferType const *buffer) const 128 //TODO remove
129 void setProperty(const QByteArray &key, const QVariant &value)
47 { 130 {
48 if (mReadAccessors.contains(key)) { 131 }
49 auto accessor = mReadAccessors.value(key); 132
50 return accessor(buffer); 133 virtual QVariant getProperty(const QByteArray &key) const
134 {
135 if (mResourceBuffer && mResourceMapper->hasMapping(key)) {
136 return mResourceMapper->getProperty(key, mResourceBuffer);
137 } else if (mLocalBuffer && mLocalMapper->hasMapping(key)) {
138 return mLocalMapper->getProperty(key, mLocalBuffer);
51 } 139 }
140 qWarning() << "no mapping available for key " << key;
52 return QVariant(); 141 return QVariant();
53 } 142 }
54 QHash<QString, std::function<QVariant(BufferType const *)> > mReadAccessors; 143
55 QHash<QString, std::function<void(const QVariant &, BufferType*)> > mWriteAccessors; 144 virtual QList<QByteArray> availableProperties() const
145 {
146 QList<QByteArray> props;
147 props << mResourceMapper->availableProperties();
148 props << mLocalMapper->availableProperties();
149 return props;
150 }
151
152 LocalBuffer const *mLocalBuffer;
153 ResourceBuffer const *mResourceBuffer;
154 QSharedPointer<ReadPropertyMapper<LocalBuffer> > mLocalMapper;
155 QSharedPointer<ReadPropertyMapper<ResourceBuffer> > mResourceMapper;
56}; 156};
57 157
58//The factory should define how to go from an entitybuffer (local + resource buffer), to a domain type adapter. 158/**
59//It defines how values are split accross local and resource buffer. 159 * Initializes the local property mapper.
60//This is required by the facade the read the value, and by the pipeline preprocessors to access the domain values in a generic way. 160 *
61// template<typename DomainType, typename LocalBuffer, typename ResourceBuffer> 161 * Provide an implementation for each application domain type.
62// class DomainTypeAdaptorFactory 162 */
63// { 163template <class T>
64// }; 164QSharedPointer<ReadPropertyMapper<T> > initializeReadPropertyMapper();
165
166template <class T>
167QSharedPointer<WritePropertyMapper<T> > initializeWritePropertyMapper();
65 168
66template<typename DomainType, typename LocalBuffer, typename ResourceBuffer> 169/**
67class DomainTypeAdaptorFactory/* <typename DomainType, LocalBuffer, ResourceBuffer> */ 170 * The factory should define how to go from an entitybuffer (local + resource buffer), to a domain type adapter.
171 * It defines how values are split accross local and resource buffer.
172 * This is required by the facade the read the value, and by the pipeline preprocessors to access the domain values in a generic way.
173 */
174template<typename DomainType, typename LocalBuffer, typename ResourceBuffer, typename LocalBuilder, typename ResourceBuilder>
175class DomainTypeAdaptorFactory
68{ 176{
69public: 177public:
178 DomainTypeAdaptorFactory() :
179 mLocalMapper(initializeReadPropertyMapper<LocalBuffer>()),
180 mResourceMapper(QSharedPointer<ReadPropertyMapper<ResourceBuffer> >::create()),
181 mLocalWriteMapper(initializeWritePropertyMapper<LocalBuilder>()),
182 mResourceWriteMapper(QSharedPointer<WritePropertyMapper<ResourceBuilder> >::create())
183 {};
70 virtual ~DomainTypeAdaptorFactory() {}; 184 virtual ~DomainTypeAdaptorFactory() {};
71 virtual QSharedPointer<Akonadi2::Domain::BufferAdaptor> createAdaptor(const Akonadi2::Entity &entity) = 0; 185
72 virtual void createBuffer(const Akonadi2::Domain::Event &event, flatbuffers::FlatBufferBuilder &fbb) {}; 186 /**
187 * Creates an adaptor for the given domain and resource types.
188 *
189 * This returns by default a GenericBufferAdaptor initialized with the corresponding property mappers.
190 */
191 virtual QSharedPointer<Akonadi2::ApplicationDomain::BufferAdaptor> createAdaptor(const Akonadi2::Entity &entity)
192 {
193 const auto resourceBuffer = Akonadi2::EntityBuffer::readBuffer<ResourceBuffer>(entity.resource());
194 const auto localBuffer = Akonadi2::EntityBuffer::readBuffer<LocalBuffer>(entity.local());
195 // const auto metadataBuffer = Akonadi2::EntityBuffer::readBuffer<Akonadi2::Metadata>(entity.metadata());
196
197 auto adaptor = QSharedPointer<GenericBufferAdaptor<LocalBuffer, ResourceBuffer> >::create();
198 adaptor->mLocalBuffer = localBuffer;
199 adaptor->mLocalMapper = mLocalMapper;
200 adaptor->mResourceBuffer = resourceBuffer;
201 adaptor->mResourceMapper = mResourceMapper;
202 return adaptor;
203 }
204
205 virtual void createBuffer(const Akonadi2::ApplicationDomain::Event &event, flatbuffers::FlatBufferBuilder &fbb) {};
73 206
74protected: 207protected:
75 QSharedPointer<PropertyMapper<LocalBuffer> > mLocalMapper; 208 QSharedPointer<ReadPropertyMapper<LocalBuffer> > mLocalMapper;
76 QSharedPointer<PropertyMapper<ResourceBuffer> > mResourceMapper; 209 QSharedPointer<ReadPropertyMapper<ResourceBuffer> > mResourceMapper;
210 QSharedPointer<WritePropertyMapper<LocalBuilder> > mLocalWriteMapper;
211 QSharedPointer<WritePropertyMapper<ResourceBuilder> > mResourceWriteMapper;
77}; 212};
78 213
79 214
diff --git a/common/entitybuffer.cpp b/common/entitybuffer.cpp
index 5ba4afe..b555ac3 100644
--- a/common/entitybuffer.cpp
+++ b/common/entitybuffer.cpp
@@ -56,17 +56,24 @@ void EntityBuffer::extractResourceBuffer(void *dataValue, int dataSize, const st
56 } 56 }
57} 57}
58 58
59void EntityBuffer::assembleEntityBuffer(flatbuffers::FlatBufferBuilder &fbb, void const *metadataData, size_t metadataSize, void const *resourceData, size_t resourceSize, void const *localData, size_t localSize) 59flatbuffers::Offset<flatbuffers::Vector<uint8_t> > EntityBuffer::appendAsVector(flatbuffers::FlatBufferBuilder &fbb, void const *data, size_t size)
60{ 60{
61 auto metadata = fbb.CreateVector<uint8_t>(static_cast<uint8_t const*>(metadataData), metadataSize); 61 //Since we do memcpy trickery, this will only work on little endian
62 auto resource = fbb.CreateVector<uint8_t>(static_cast<uint8_t const*>(resourceData), resourceSize); 62 assert(FLATBUFFERS_LITTLEENDIAN);
63 auto local = fbb.CreateVector<uint8_t>(static_cast<uint8_t const*>(localData), localSize); 63 auto metadata = fbb.CreateUninitializedVector<uint8_t>(size);
64 auto builder = Akonadi2::EntityBuilder(fbb); 64 {
65 builder.add_metadata(metadata); 65 auto ptr = reinterpret_cast<flatbuffers::Vector<uint8_t> *>(fbb.GetBufferPointer())->Data();
66 builder.add_resource(resource); 66 std::memcpy((void*)ptr, data, size);
67 builder.add_local(local); 67 }
68 return metadata;
69}
68 70
69 auto buffer = builder.Finish(); 71void EntityBuffer::assembleEntityBuffer(flatbuffers::FlatBufferBuilder &fbb, void const *metadataData, size_t metadataSize, void const *resourceData, size_t resourceSize, void const *localData, size_t localSize)
70 Akonadi2::FinishEntityBuffer(fbb, buffer); 72{
73 auto metadata = appendAsVector(fbb, metadataData, metadataSize);
74 auto resource = appendAsVector(fbb, resourceData, resourceSize);
75 auto local = appendAsVector(fbb, localData, localSize);
76 auto entity = Akonadi2::CreateEntity(fbb, metadata, resource, local);
77 Akonadi2::FinishEntityBuffer(fbb, entity);
71} 78}
72 79
diff --git a/common/entitybuffer.h b/common/entitybuffer.h
index 097b450..82152c9 100644
--- a/common/entitybuffer.h
+++ b/common/entitybuffer.h
@@ -15,7 +15,33 @@ public:
15 const Entity &entity(); 15 const Entity &entity();
16 16
17 static void extractResourceBuffer(void *dataValue, int dataSize, const std::function<void(const uint8_t *, size_t size)> &handler); 17 static void extractResourceBuffer(void *dataValue, int dataSize, const std::function<void(const uint8_t *, size_t size)> &handler);
18 /*
19 * TODO: Ideally we would be passing references to vectors in the same bufferbuilder, to avoid needlessly copying data.
20 * Unfortunately I couldn't find a way to cast a table to a vector<uint8_t> reference.
21 * We can't use union's either (which would allow to have a field that stores a selection of tables), as we don't want to modify
22 * the entity schema for each resource's buffers.
23 */
18 static void assembleEntityBuffer(flatbuffers::FlatBufferBuilder &fbb, void const *metadataData, size_t metadataSize, void const *resourceData, size_t resourceSize, void const *localData, size_t localSize); 24 static void assembleEntityBuffer(flatbuffers::FlatBufferBuilder &fbb, void const *metadataData, size_t metadataSize, void const *resourceData, size_t resourceSize, void const *localData, size_t localSize);
25 static flatbuffers::Offset<flatbuffers::Vector<uint8_t> > appendAsVector(flatbuffers::FlatBufferBuilder &fbb, void const *data, size_t size);
26 template<typename T>
27 static const T *readBuffer(const uint8_t *data, int size)
28 {
29 flatbuffers::Verifier verifier(data, size);
30 if (verifier.VerifyBuffer<T>()) {
31 return flatbuffers::GetRoot<T>(data);
32 }
33 return nullptr;
34 }
35
36 template<typename T>
37 static const T *readBuffer(const flatbuffers::Vector<uint8_t> *data)
38 {
39 if (data) {
40 return readBuffer<T>(data->Data(), data->size());
41 }
42 return nullptr;
43 }
44
19 45
20private: 46private:
21 const Entity *mEntity; 47 const Entity *mEntity;
diff --git a/common/facade.h b/common/facade.h
new file mode 100644
index 0000000..98bcb38
--- /dev/null
+++ b/common/facade.h
@@ -0,0 +1,88 @@
1/*
2 * Copyright (C) 2014 Christian Mollekopf <chrigi_1@fastmail.fm>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#pragma once
21
22#include "clientapi.h"
23
24#include <QByteArray>
25
26#include "async/src/async.h"
27#include "resourceaccess.h"
28#include "commands.h"
29#include "createentity_generated.h"
30#include "domainadaptor.h"
31#include "entitybuffer.h"
32
33namespace Akonadi2 {
34 class ResourceAccess;
35/**
36 * Default facade implementation for resources that are implemented in a separate process using the ResourceAccess class.
37 */
38template <typename DomainType>
39class GenericFacade: public Akonadi2::StoreFacade<DomainType>
40{
41public:
42 GenericFacade(const QByteArray &resourceIdentifier)
43 : Akonadi2::StoreFacade<DomainType>(),
44 mResourceAccess(new ResourceAccess(resourceIdentifier))
45 {
46 }
47
48 ~GenericFacade()
49 {
50 }
51
52protected:
53 Async::Job<void> sendCreateCommand(const QByteArray &t, const QByteArray &buffer)
54 {
55 flatbuffers::FlatBufferBuilder fbb;
56 //This is the resource buffer type and not the domain type
57 auto type = fbb.CreateString(t.constData());
58 auto delta = Akonadi2::EntityBuffer::appendAsVector(fbb, buffer.constData(), buffer.size());
59 auto location = Akonadi2::Commands::CreateCreateEntity(fbb, type, delta);
60 Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location);
61 mResourceAccess->open();
62 return mResourceAccess->sendCommand(Akonadi2::Commands::CreateEntityCommand, fbb);
63 }
64
65 Async::Job<void> synchronizeResource(bool sync, bool processAll)
66 {
67 //TODO check if a sync is necessary
68 //TODO Only sync what was requested
69 //TODO timeout
70 //TODO the synchronization should normally not be necessary: We just return what is already available.
71
72 if (sync || processAll) {
73 return Async::start<void>([=](Async::Future<void> &future) {
74 mResourceAccess->open();
75 mResourceAccess->synchronizeResource(sync, processAll).then<void>([&future]() {
76 future.setFinished();
77 }).exec();
78 });
79 }
80 return Async::null<void>();
81 }
82
83private:
84 //TODO use one resource access instance per application => make static
85 QSharedPointer<Akonadi2::ResourceAccess> mResourceAccess;
86};
87
88}
diff --git a/common/resource.h b/common/resource.h
index bcce229..18a6827 100644
--- a/common/resource.h
+++ b/common/resource.h
@@ -26,10 +26,12 @@
26namespace Akonadi2 26namespace Akonadi2
27{ 27{
28 28
29/**
30 * Resource interface
31 */
29class AKONADI2COMMON_EXPORT Resource 32class AKONADI2COMMON_EXPORT Resource
30{ 33{
31public: 34public:
32 //TODO: configuration
33 Resource(); 35 Resource();
34 virtual ~Resource(); 36 virtual ~Resource();
35 37
@@ -44,6 +46,9 @@ private:
44 Private * const d; 46 Private * const d;
45}; 47};
46 48
49/**
50 * Factory interface for resource to implement.
51 */
47class ResourceFactory : public QObject 52class ResourceFactory : public QObject
48{ 53{
49public: 54public:
diff --git a/common/resourceaccess.cpp b/common/resourceaccess.cpp
index 7320e50..7a343f9 100644
--- a/common/resourceaccess.cpp
+++ b/common/resourceaccess.cpp
@@ -64,8 +64,8 @@ public:
64class ResourceAccess::Private 64class ResourceAccess::Private
65{ 65{
66public: 66public:
67 Private(const QString &name, ResourceAccess *ra); 67 Private(const QByteArray &name, ResourceAccess *ra);
68 QString resourceName; 68 QByteArray resourceName;
69 QLocalSocket *socket; 69 QLocalSocket *socket;
70 QTimer *tryOpenTimer; 70 QTimer *tryOpenTimer;
71 bool startingProcess; 71 bool startingProcess;
@@ -77,7 +77,7 @@ public:
77 uint messageId; 77 uint messageId;
78}; 78};
79 79
80ResourceAccess::Private::Private(const QString &name, ResourceAccess *q) 80ResourceAccess::Private::Private(const QByteArray &name, ResourceAccess *q)
81 : resourceName(name), 81 : resourceName(name),
82 socket(new QLocalSocket(q)), 82 socket(new QLocalSocket(q)),
83 tryOpenTimer(new QTimer(q)), 83 tryOpenTimer(new QTimer(q)),
@@ -87,7 +87,7 @@ ResourceAccess::Private::Private(const QString &name, ResourceAccess *q)
87{ 87{
88} 88}
89 89
90ResourceAccess::ResourceAccess(const QString &resourceName, QObject *parent) 90ResourceAccess::ResourceAccess(const QByteArray &resourceName, QObject *parent)
91 : QObject(parent), 91 : QObject(parent),
92 d(new Private(resourceName, this)) 92 d(new Private(resourceName, this))
93{ 93{
@@ -112,7 +112,7 @@ ResourceAccess::~ResourceAccess()
112 112
113} 113}
114 114
115QString ResourceAccess::resourceName() const 115QByteArray ResourceAccess::resourceName() const
116{ 116{
117 return d->resourceName; 117 return d->resourceName;
118} 118}
diff --git a/common/resourceaccess.h b/common/resourceaccess.h
index a5a2547..088bf36 100644
--- a/common/resourceaccess.h
+++ b/common/resourceaccess.h
@@ -35,10 +35,10 @@ class ResourceAccess : public QObject
35 Q_OBJECT 35 Q_OBJECT
36 36
37public: 37public:
38 ResourceAccess(const QString &resourceName, QObject *parent = 0); 38 ResourceAccess(const QByteArray &resourceName, QObject *parent = 0);
39 ~ResourceAccess(); 39 ~ResourceAccess();
40 40
41 QString resourceName() const; 41 QByteArray resourceName() const;
42 bool isReady() const; 42 bool isReady() const;
43 43
44 Async::Job<void> sendCommand(int commandId); 44 Async::Job<void> sendCommand(int commandId);
diff --git a/common/storage.h b/common/storage.h
index 78faac0..09365b0 100644
--- a/common/storage.h
+++ b/common/storage.h
@@ -98,7 +98,7 @@ public:
98 * Set the default error handler. 98 * Set the default error handler.
99 */ 99 */
100 void setDefaultErrorHandler(const std::function<void(const Storage::Error &error)> &errorHandler); 100 void setDefaultErrorHandler(const std::function<void(const Storage::Error &error)> &errorHandler);
101 std::function<void(const Storage::Error &error)> defaultErrorHandler(); 101 std::function<void(const Storage::Error &error)> defaultErrorHandler() const;
102 102
103 /** 103 /**
104 * A basic error handler that writes to std::cerr. 104 * A basic error handler that writes to std::cerr.
diff --git a/common/storage_common.cpp b/common/storage_common.cpp
index 5728096..65f6e57 100644
--- a/common/storage_common.cpp
+++ b/common/storage_common.cpp
@@ -46,7 +46,7 @@ void Storage::setDefaultErrorHandler(const std::function<void(const Storage::Err
46 mErrorHandler = errorHandler; 46 mErrorHandler = errorHandler;
47} 47}
48 48
49std::function<void(const Storage::Error &error)> Storage::defaultErrorHandler() 49std::function<void(const Storage::Error &error)> Storage::defaultErrorHandler() const
50{ 50{
51 if (mErrorHandler) { 51 if (mErrorHandler) {
52 return mErrorHandler; 52 return mErrorHandler;
diff --git a/common/storage_lmdb.cpp b/common/storage_lmdb.cpp
index 4fcb11f..7bbf8b5 100644
--- a/common/storage_lmdb.cpp
+++ b/common/storage_lmdb.cpp
@@ -425,11 +425,11 @@ qint64 Storage::diskUsage() const
425void Storage::removeFromDisk() const 425void Storage::removeFromDisk() const
426{ 426{
427 const QString fullPath(d->storageRoot + '/' + d->name); 427 const QString fullPath(d->storageRoot + '/' + d->name);
428 qDebug() << "removing " << fullPath;
429 QMutexLocker locker(&d->sMutex); 428 QMutexLocker locker(&d->sMutex);
430 QDir dir(fullPath); 429 QDir dir(fullPath);
431 if (!dir.removeRecursively()) { 430 if (!dir.removeRecursively()) {
432 qWarning() << "Failed to remove directory" << d->storageRoot << d->name; 431 Error error(d->name.toLatin1(), ErrorCodes::GenericError, QString("Failed to remove directory %1 %2").arg(d->storageRoot).arg(d->name).toLatin1());
432 defaultErrorHandler()(error);
433 } 433 }
434 auto env = d->sEnvironments.take(fullPath); 434 auto env = d->sEnvironments.take(fullPath);
435 mdb_env_close(env); 435 mdb_env_close(env);
diff --git a/common/test/clientapitest.cpp b/common/test/clientapitest.cpp
index c9e4d6d..24b3fb9 100644
--- a/common/test/clientapitest.cpp
+++ b/common/test/clientapitest.cpp
@@ -4,14 +4,14 @@
4 4
5#include "../clientapi.h" 5#include "../clientapi.h"
6 6
7class DummyResourceFacade : public Akonadi2::StoreFacade<Akonadi2::Domain::Event> 7class DummyResourceFacade : public Akonadi2::StoreFacade<Akonadi2::ApplicationDomain::Event>
8{ 8{
9public: 9public:
10 ~DummyResourceFacade(){}; 10 ~DummyResourceFacade(){};
11 virtual Async::Job<void> create(const Akonadi2::Domain::Event &domainObject){ return Async::null<void>(); }; 11 virtual Async::Job<void> create(const Akonadi2::ApplicationDomain::Event &domainObject){ return Async::null<void>(); };
12 virtual Async::Job<void> modify(const Akonadi2::Domain::Event &domainObject){ return Async::null<void>(); }; 12 virtual Async::Job<void> modify(const Akonadi2::ApplicationDomain::Event &domainObject){ return Async::null<void>(); };
13 virtual Async::Job<void> remove(const Akonadi2::Domain::Event &domainObject){ return Async::null<void>(); }; 13 virtual Async::Job<void> remove(const Akonadi2::ApplicationDomain::Event &domainObject){ return Async::null<void>(); };
14 virtual Async::Job<void> load(const Akonadi2::Query &query, const std::function<void(const Akonadi2::Domain::Event::Ptr &)> &resultCallback) 14 virtual Async::Job<void> load(const Akonadi2::Query &query, const std::function<void(const Akonadi2::ApplicationDomain::Event::Ptr &)> &resultCallback)
15 { 15 {
16 return Async::start<void>([this, resultCallback](Async::Future<void> &future) { 16 return Async::start<void>([this, resultCallback](Async::Future<void> &future) {
17 qDebug() << "load called"; 17 qDebug() << "load called";
@@ -22,7 +22,7 @@ public:
22 }); 22 });
23 } 23 }
24 24
25 QList<Akonadi2::Domain::Event::Ptr> results; 25 QList<Akonadi2::ApplicationDomain::Event::Ptr> results;
26}; 26};
27 27
28class ClientAPITest : public QObject 28class ClientAPITest : public QObject
@@ -33,14 +33,14 @@ private Q_SLOTS:
33 void testLoad() 33 void testLoad()
34 { 34 {
35 DummyResourceFacade facade; 35 DummyResourceFacade facade;
36 facade.results << QSharedPointer<Akonadi2::Domain::Event>::create("resource", "id", 0, QSharedPointer<Akonadi2::Domain::BufferAdaptor>()); 36 facade.results << QSharedPointer<Akonadi2::ApplicationDomain::Event>::create("resource", "id", 0, QSharedPointer<Akonadi2::ApplicationDomain::BufferAdaptor>());
37 37
38 Akonadi2::FacadeFactory::instance().registerFacade<Akonadi2::Domain::Event, DummyResourceFacade>("dummyresource", [facade](){ return new DummyResourceFacade(facade); }); 38 Akonadi2::FacadeFactory::instance().registerFacade<Akonadi2::ApplicationDomain::Event, DummyResourceFacade>("dummyresource", [facade](){ return new DummyResourceFacade(facade); });
39 39
40 Akonadi2::Query query; 40 Akonadi2::Query query;
41 query.resources << "dummyresource"; 41 query.resources << "dummyresource";
42 42
43 async::SyncListResult<Akonadi2::Domain::Event::Ptr> result(Akonadi2::Store::load<Akonadi2::Domain::Event>(query)); 43 async::SyncListResult<Akonadi2::ApplicationDomain::Event::Ptr> result(Akonadi2::Store::load<Akonadi2::ApplicationDomain::Event>(query));
44 result.exec(); 44 result.exec();
45 QCOMPARE(result.size(), 1); 45 QCOMPARE(result.size(), 1);
46 } 46 }