summaryrefslogtreecommitdiffstats
path: root/dummyresource
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2015-01-03 00:08:44 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2015-01-03 00:08:44 +0100
commit4067462b0a27984df84b0379c19122d574253dfb (patch)
treee6a413a575b7fd4062da6474907bffd68155706f /dummyresource
parent91d915a09b7d52c10edb1d4c1298fc2885b8a257 (diff)
downloadsink-4067462b0a27984df84b0379c19122d574253dfb.tar.gz
sink-4067462b0a27984df84b0379c19122d574253dfb.zip
Shared domain adaptors between resource and facade.
Diffstat (limited to 'dummyresource')
-rw-r--r--dummyresource/CMakeLists.txt2
-rw-r--r--dummyresource/domainadaptor.cpp101
-rw-r--r--dummyresource/domainadaptor.h14
-rw-r--r--dummyresource/facade.cpp92
-rw-r--r--dummyresource/facade.h50
-rw-r--r--dummyresource/resourcefactory.cpp12
6 files changed, 126 insertions, 145 deletions
diff --git a/dummyresource/CMakeLists.txt b/dummyresource/CMakeLists.txt
index a2caf29..abd315f 100644
--- a/dummyresource/CMakeLists.txt
+++ b/dummyresource/CMakeLists.txt
@@ -5,7 +5,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
5 5
6generate_flatbuffers(dummycalendar) 6generate_flatbuffers(dummycalendar)
7 7
8add_library(${PROJECT_NAME} SHARED facade.cpp resourcefactory.cpp) 8add_library(${PROJECT_NAME} SHARED facade.cpp resourcefactory.cpp domainadaptor.cpp)
9qt5_use_modules(${PROJECT_NAME} Core Network) 9qt5_use_modules(${PROJECT_NAME} Core Network)
10target_link_libraries(${PROJECT_NAME} akonadi2common) 10target_link_libraries(${PROJECT_NAME} akonadi2common)
11 11
diff --git a/dummyresource/domainadaptor.cpp b/dummyresource/domainadaptor.cpp
new file mode 100644
index 0000000..5d046ff
--- /dev/null
+++ b/dummyresource/domainadaptor.cpp
@@ -0,0 +1,101 @@
1
2#include "domainadaptor.h"
3
4#include <QDebug>
5#include <functional>
6
7#include "dummycalendar_generated.h"
8#include "event_generated.h"
9#include "entity_generated.h"
10#include "metadata_generated.h"
11#include "domainadaptor.h"
12#include <common/entitybuffer.h>
13
14using namespace DummyCalendar;
15using namespace flatbuffers;
16
17using namespace DummyCalendar;
18using namespace flatbuffers;
19
20//This will become a generic implementation that simply takes the resource buffer and local buffer pointer
21class DummyEventAdaptor : public Akonadi2::Domain::BufferAdaptor
22{
23public:
24 DummyEventAdaptor()
25 : BufferAdaptor()
26 {
27
28 }
29
30 void setProperty(const QString &key, const QVariant &value)
31 {
32 if (mResourceMapper->mWriteAccessors.contains(key)) {
33 // mResourceMapper.setProperty(key, value, mResourceBuffer);
34 } else {
35 // mLocalMapper.;
36 }
37 }
38
39 virtual QVariant getProperty(const QString &key) const
40 {
41 if (mResourceBuffer && mResourceMapper->mReadAccessors.contains(key)) {
42 return mResourceMapper->getProperty(key, mResourceBuffer);
43 } else if (mLocalBuffer) {
44 return mLocalMapper->getProperty(key, mLocalBuffer);
45 }
46 return QVariant();
47 }
48
49 Akonadi2::Domain::Buffer::Event const *mLocalBuffer;
50 DummyEvent const *mResourceBuffer;
51
52 QSharedPointer<PropertyMapper<Akonadi2::Domain::Buffer::Event> > mLocalMapper;
53 QSharedPointer<PropertyMapper<DummyEvent> > mResourceMapper;
54};
55
56
57DummyEventAdaptorFactory::DummyEventAdaptorFactory()
58 : DomainTypeAdaptorFactory()
59{
60 mResourceMapper = QSharedPointer<PropertyMapper<DummyEvent> >::create();
61 mResourceMapper->mReadAccessors.insert("summary", [](DummyEvent const *buffer) -> QVariant {
62 return QString::fromStdString(buffer->summary()->c_str());
63 });
64 //TODO set accessors for all properties
65
66}
67
68QSharedPointer<Akonadi2::Domain::BufferAdaptor> DummyEventAdaptorFactory::createAdaptor(const Akonadi2::Entity &entity)
69{
70 DummyEvent const *resourceBuffer = 0;
71 if (auto resourceData = entity.resource()) {
72 flatbuffers::Verifier verifyer(resourceData->Data(), resourceData->size());
73 if (VerifyDummyEventBuffer(verifyer)) {
74 resourceBuffer = GetDummyEvent(resourceData);
75 }
76 }
77
78 Akonadi2::Metadata const *metadataBuffer = 0;
79 if (auto metadataData = entity.metadata()) {
80 flatbuffers::Verifier verifyer(metadataData->Data(), metadataData->size());
81 if (Akonadi2::VerifyMetadataBuffer(verifyer)) {
82 metadataBuffer = Akonadi2::GetMetadata(metadataData);
83 }
84 }
85
86 Akonadi2::Domain::Buffer::Event const *localBuffer = 0;
87 if (auto localData = entity.local()) {
88 flatbuffers::Verifier verifyer(localData->Data(), localData->size());
89 if (Akonadi2::Domain::Buffer::VerifyEventBuffer(verifyer)) {
90 localBuffer = Akonadi2::Domain::Buffer::GetEvent(localData);
91 }
92 }
93
94 auto adaptor = QSharedPointer<DummyEventAdaptor>::create();
95 adaptor->mLocalBuffer = localBuffer;
96 adaptor->mResourceBuffer = resourceBuffer;
97 adaptor->mResourceMapper = mResourceMapper;
98 adaptor->mLocalMapper = mLocalMapper;
99 return adaptor;
100}
101
diff --git a/dummyresource/domainadaptor.h b/dummyresource/domainadaptor.h
new file mode 100644
index 0000000..881b7f3
--- /dev/null
+++ b/dummyresource/domainadaptor.h
@@ -0,0 +1,14 @@
1
2#pragma once
3
4#include "common/domainadaptor.h"
5#include "event_generated.h"
6#include "dummycalendar_generated.h"
7#include "entity_generated.h"
8
9class DummyEventAdaptorFactory : public DomainTypeAdaptorFactory<Akonadi2::Domain::Event, Akonadi2::Domain::Buffer::Event, DummyCalendar::DummyEvent>
10{
11public:
12 DummyEventAdaptorFactory();
13 virtual QSharedPointer<Akonadi2::Domain::BufferAdaptor> createAdaptor(const Akonadi2::Entity &entity);
14};
diff --git a/dummyresource/facade.cpp b/dummyresource/facade.cpp
index c167297..b4d98c6 100644
--- a/dummyresource/facade.cpp
+++ b/dummyresource/facade.cpp
@@ -28,92 +28,17 @@
28#include "event_generated.h" 28#include "event_generated.h"
29#include "entity_generated.h" 29#include "entity_generated.h"
30#include "metadata_generated.h" 30#include "metadata_generated.h"
31#include "domainadaptor.h"
31#include <common/entitybuffer.h> 32#include <common/entitybuffer.h>
32 33
33using namespace DummyCalendar; 34using namespace DummyCalendar;
34using namespace flatbuffers; 35using namespace flatbuffers;
35 36
36//This will become a generic implementation that simply takes the resource buffer and local buffer pointer
37class DummyEventAdaptor : public Akonadi2::Domain::BufferAdaptor
38{
39public:
40 DummyEventAdaptor()
41 : BufferAdaptor()
42 {
43
44 }
45
46 void setProperty(const QString &key, const QVariant &value)
47 {
48 if (mResourceMapper->mWriteAccessors.contains(key)) {
49 // mResourceMapper.setProperty(key, value, mResourceBuffer);
50 } else {
51 // mLocalMapper.;
52 }
53 }
54
55 virtual QVariant getProperty(const QString &key) const
56 {
57 if (mResourceBuffer && mResourceMapper->mReadAccessors.contains(key)) {
58 return mResourceMapper->getProperty(key, mResourceBuffer);
59 } else if (mLocalBuffer) {
60 return mLocalMapper->getProperty(key, mLocalBuffer);
61 }
62 return QVariant();
63 }
64
65 Akonadi2::Domain::Buffer::Event const *mLocalBuffer;
66 DummyEvent const *mResourceBuffer;
67
68 QSharedPointer<PropertyMapper<Akonadi2::Domain::Buffer::Event> > mLocalMapper;
69 QSharedPointer<PropertyMapper<DummyEvent> > mResourceMapper;
70};
71
72template<>
73QSharedPointer<Akonadi2::Domain::BufferAdaptor> DomainTypeAdaptorFactory<typename Akonadi2::Domain::Event, typename Akonadi2::Domain::Buffer::Event, DummyEvent>::createAdaptor(const Akonadi2::Entity &entity)
74{
75 DummyEvent const *resourceBuffer = 0;
76 if (auto resourceData = entity.resource()) {
77 flatbuffers::Verifier verifyer(resourceData->Data(), resourceData->size());
78 if (VerifyDummyEventBuffer(verifyer)) {
79 resourceBuffer = GetDummyEvent(resourceData);
80 }
81 }
82
83 Akonadi2::Metadata const *metadataBuffer = 0;
84 if (auto metadataData = entity.metadata()) {
85 flatbuffers::Verifier verifyer(metadataData->Data(), metadataData->size());
86 if (Akonadi2::VerifyMetadataBuffer(verifyer)) {
87 metadataBuffer = Akonadi2::GetMetadata(metadataData);
88 }
89 }
90
91 Akonadi2::Domain::Buffer::Event const *localBuffer = 0;
92 if (auto localData = entity.local()) {
93 flatbuffers::Verifier verifyer(localData->Data(), localData->size());
94 if (Akonadi2::Domain::Buffer::VerifyEventBuffer(verifyer)) {
95 localBuffer = Akonadi2::Domain::Buffer::GetEvent(localData);
96 }
97 }
98
99 auto adaptor = QSharedPointer<DummyEventAdaptor>::create();
100 adaptor->mLocalBuffer = localBuffer;
101 adaptor->mResourceBuffer = resourceBuffer;
102 adaptor->mResourceMapper = mResourceMapper;
103 adaptor->mLocalMapper = mLocalMapper;
104 return adaptor;
105}
106
107DummyResourceFacade::DummyResourceFacade() 37DummyResourceFacade::DummyResourceFacade()
108 : Akonadi2::StoreFacade<Akonadi2::Domain::Event>(), 38 : Akonadi2::StoreFacade<Akonadi2::Domain::Event>(),
109 mResourceAccess(new Akonadi2::ResourceAccess("org.kde.dummy")), 39 mResourceAccess(new Akonadi2::ResourceAccess("org.kde.dummy")),
110 mFactory(new DomainTypeAdaptorFactory<Akonadi2::Domain::Event, Akonadi2::Domain::Buffer::Event, DummyCalendar::DummyEvent>()) 40 mFactory(new DummyEventAdaptorFactory)
111{ 41{
112 auto mapper = QSharedPointer<PropertyMapper<DummyEvent> >::create();
113 mapper->mReadAccessors.insert("summary", [](DummyEvent const *buffer) -> QVariant {
114 return QString::fromStdString(buffer->summary()->c_str());
115 });
116 mFactory->mResourceMapper = mapper;
117} 42}
118 43
119DummyResourceFacade::~DummyResourceFacade() 44DummyResourceFacade::~DummyResourceFacade()
@@ -135,19 +60,6 @@ void DummyResourceFacade::remove(const Akonadi2::Domain::Event &domainObject)
135 //Create message buffer and send to resource 60 //Create message buffer and send to resource
136} 61}
137 62
138//Key.value property map using enum or strings with qvariant, or rather typesafe API?
139//typesafe is a shitload more work that we can avoid
140//
141//The Event base implementaiton could take a pointer to a single property mapper,
142//and a void pointer to the mmapped region. => event is copyable and stack allocatable and we avoid large amounts of heap allocated objects
143//-The mapper should in this case live in the other thread
144//-default property mapper implementation can answer "is property X supported?"
145//-how do we free/munmap the data if we don't know when no one references it any longer? => no munmap needed, but read transaction to keep pointer alive
146//-we could bind the lifetime to the query
147//=> perhaps do heap allocate and use smart pointer?
148//
149
150
151static std::function<bool(const std::string &key, DummyEvent const *buffer)> prepareQuery(const Akonadi2::Query &query) 63static std::function<bool(const std::string &key, DummyEvent const *buffer)> prepareQuery(const Akonadi2::Query &query)
152{ 64{
153 //Compose some functions to make query matching fast. 65 //Compose some functions to make query matching fast.
diff --git a/dummyresource/facade.h b/dummyresource/facade.h
index 46b27ef..e01d254 100644
--- a/dummyresource/facade.h
+++ b/dummyresource/facade.h
@@ -21,62 +21,16 @@
21 21
22#include "common/clientapi.h" 22#include "common/clientapi.h"
23#include "common/storage.h" 23#include "common/storage.h"
24#include "resourcefactory.h"
24#include "entity_generated.h" 25#include "entity_generated.h"
25#include "event_generated.h" 26#include "event_generated.h"
26#include "dummycalendar_generated.h" 27#include "dummycalendar_generated.h"
28#include "common/domainadaptor.h"
27 29
28namespace Akonadi2 { 30namespace Akonadi2 {
29 class ResourceAccess; 31 class ResourceAccess;
30} 32}
31 33
32/**
33 * The property mapper holds accessor functions for all properties.
34 *
35 * It is by default initialized with accessors that access the local-only buffer,
36 * and resource simply have to overwrite those accessors.
37 */
38template<typename BufferType>
39class PropertyMapper
40{
41public:
42 void setProperty(const QString &key, const QVariant &value, BufferType *buffer)
43 {
44 if (mWriteAccessors.contains(key)) {
45 auto accessor = mWriteAccessors.value(key);
46 return accessor(value, buffer);
47 }
48 }
49
50 virtual QVariant getProperty(const QString &key, BufferType const *buffer) const
51 {
52 if (mReadAccessors.contains(key)) {
53 auto accessor = mReadAccessors.value(key);
54 return accessor(buffer);
55 }
56 return QVariant();
57 }
58 QHash<QString, std::function<QVariant(BufferType const *)> > mReadAccessors;
59 QHash<QString, std::function<void(const QVariant &, BufferType*)> > mWriteAccessors;
60};
61
62//The factory should define how to go from an entitybuffer (local + resource buffer), to a domain type adapter.
63//It defines how values are split accross local and resource buffer.
64//This is required by the facade the read the value, and by the pipeline preprocessors to access the domain values in a generic way.
65template<typename DomainType, typename LocalBuffer, typename ResourceBuffer>
66class DomainTypeAdaptorFactory
67{
68};
69
70template<typename LocalBuffer, typename ResourceBuffer>
71class DomainTypeAdaptorFactory<typename Akonadi2::Domain::Event, LocalBuffer, ResourceBuffer>
72{
73public:
74 QSharedPointer<Akonadi2::Domain::BufferAdaptor> createAdaptor(const Akonadi2::Entity &entity);
75
76// private:
77 QSharedPointer<PropertyMapper<LocalBuffer> > mLocalMapper;
78 QSharedPointer<PropertyMapper<ResourceBuffer> > mResourceMapper;
79};
80 34
81class DummyResourceFacade : public Akonadi2::StoreFacade<Akonadi2::Domain::Event> 35class DummyResourceFacade : public Akonadi2::StoreFacade<Akonadi2::Domain::Event>
82{ 36{
diff --git a/dummyresource/resourcefactory.cpp b/dummyresource/resourcefactory.cpp
index 08222c0..da6969a 100644
--- a/dummyresource/resourcefactory.cpp
+++ b/dummyresource/resourcefactory.cpp
@@ -23,6 +23,7 @@
23#include "pipeline.h" 23#include "pipeline.h"
24#include "dummycalendar_generated.h" 24#include "dummycalendar_generated.h"
25#include "metadata_generated.h" 25#include "metadata_generated.h"
26#include "domainadaptor.h"
26#include <QUuid> 27#include <QUuid>
27 28
28/* 29/*
@@ -101,14 +102,13 @@ DummyResource::DummyResource()
101 102
102void DummyResource::configurePipeline(Akonadi2::Pipeline *pipeline) 103void DummyResource::configurePipeline(Akonadi2::Pipeline *pipeline)
103{ 104{
105 auto factory = QSharedPointer<DummyEventAdaptorFactory>::create();
104 //TODO setup preprocessors for each domain type and pipeline type allowing full customization 106 //TODO setup preprocessors for each domain type and pipeline type allowing full customization
105 //Eventually the order should be self configuring, for now it's hardcoded. 107 //Eventually the order should be self configuring, for now it's hardcoded.
106 auto eventIndexer = new SimpleProcessor([](const Akonadi2::PipelineState &state) { 108 auto eventIndexer = new SimpleProcessor([factory](const Akonadi2::PipelineState &state) {
107 //FIXME 109 auto adaptor = factory->createAdaptor(state.entity());
108 // auto adaptor = QSharedPointer<DummyEventAdaptor>::create(); 110 //Here we can plug in generic preprocessors
109 // adaptor->mLocalBuffer = localBuffer; 111 qDebug() << adaptor->getProperty("summary").toString();
110 // adaptor->mResourceBuffer = resourceBuffer;
111 // adaptor->storage = storage;
112 }); 112 });
113 pipeline->setPreprocessors<Akonadi2::Domain::Event>(Akonadi2::Pipeline::NewPipeline, QVector<Akonadi2::Preprocessor*>() << eventIndexer); 113 pipeline->setPreprocessors<Akonadi2::Domain::Event>(Akonadi2::Pipeline::NewPipeline, QVector<Akonadi2::Preprocessor*>() << eventIndexer);
114} 114}