summaryrefslogtreecommitdiffstats
path: root/dummyresource/facade.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dummyresource/facade.cpp')
-rw-r--r--dummyresource/facade.cpp98
1 files changed, 75 insertions, 23 deletions
diff --git a/dummyresource/facade.cpp b/dummyresource/facade.cpp
index c2871bb..458aba6 100644
--- a/dummyresource/facade.cpp
+++ b/dummyresource/facade.cpp
@@ -25,15 +25,51 @@
25#include "common/resourceaccess.h" 25#include "common/resourceaccess.h"
26#include "common/commands.h" 26#include "common/commands.h"
27#include "dummycalendar_generated.h" 27#include "dummycalendar_generated.h"
28#include "event_generated.h"
29#include "entitybuffer_generated.h"
30#include "metadata_generated.h"
28 31
29using namespace DummyCalendar; 32using namespace DummyCalendar;
30using namespace flatbuffers; 33using namespace flatbuffers;
31 34
35/**
36 * The property mapper holds accessor functions for all properties.
37 *
38 * It is by default initialized with accessors that access the local-only buffer,
39 * and resource simply have to overwrite those accessors.
40 */
41template<typename BufferType>
42class PropertyMapper
43{
44public:
45 void setProperty(const QString &key, const QVariant &value, BufferType *buffer)
46 {
47 if (mWriteAccessors.contains(key)) {
48 auto accessor = mWriteAccessors.value(key);
49 return accessor(value, buffer);
50 }
51 }
52
53 virtual QVariant getProperty(const QString &key, BufferType const *buffer) const
54 {
55 if (mReadAccessors.contains(key)) {
56 auto accessor = mReadAccessors.value(key);
57 return accessor(buffer);
58 }
59 return QVariant();
60 }
61 QHash<QString, std::function<QVariant(BufferType const *)> > mReadAccessors;
62 QHash<QString, std::function<void(const QVariant &, BufferType*)> > mWriteAccessors;
63};
64
32DummyResourceFacade::DummyResourceFacade() 65DummyResourceFacade::DummyResourceFacade()
33 : Akonadi2::StoreFacade<Akonadi2::Domain::Event>(), 66 : Akonadi2::StoreFacade<Akonadi2::Domain::Event>(),
34 mResourceAccess(new Akonadi2::ResourceAccess("org.kde.dummy")) 67 mResourceAccess(new Akonadi2::ResourceAccess("org.kde.dummy"))
35{ 68{
36 // connect(mResourceAccess.data(), &ResourceAccess::ready, this, onReadyChanged); 69 PropertyMapper<DummyEvent> mapper;
70 mapper.mReadAccessors.insert("summary", [](DummyEvent const *buffer) -> QVariant {
71 return QString::fromStdString(buffer->summary()->c_str());
72 });
37} 73}
38 74
39DummyResourceFacade::~DummyResourceFacade() 75DummyResourceFacade::~DummyResourceFacade()
@@ -65,32 +101,43 @@ void DummyResourceFacade::remove(const Akonadi2::Domain::Event &domainObject)
65//-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 101//-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
66//-we could bind the lifetime to the query 102//-we could bind the lifetime to the query
67//=> perhaps do heap allocate and use smart pointer? 103//=> perhaps do heap allocate and use smart pointer?
68class DummyEventAdaptor : public Akonadi2::Domain::Event 104//
105
106
107//This will become a generic implementation that simply takes the resource buffer and local buffer pointer
108class DummyEventAdaptor : public Akonadi2::Domain::BufferAdaptor
69{ 109{
70public: 110public:
71 DummyEventAdaptor(const QString &resource, const QString &identifier, qint64 revision) 111 DummyEventAdaptor()
72 :Akonadi2::Domain::Event(resource, identifier, revision) 112 : BufferAdaptor()
73 { 113 {
114
74 } 115 }
75 116
76 //TODO 117 void setProperty(const QString &key, const QVariant &value)
77 // void setProperty(const QString &key, const QVariant &value) 118 {
78 // { 119 if (mResourceMapper.mWriteAccessors.contains(key)) {
79 // //Record changes to send to resource? 120 // mResourceMapper.setProperty(key, value, mResourceBuffer);
80 // //The buffer is readonly 121 } else {
81 // } 122 // mLocalMapper.;
123 }
124 }
82 125
83 virtual QVariant getProperty(const QString &key) const 126 virtual QVariant getProperty(const QString &key) const
84 { 127 {
85 if (key == "summary") { 128 if (mResourceBuffer && mResourceMapper.mReadAccessors.contains(key)) {
86 //FIXME how do we check availability for on-demand request? 129 return mResourceMapper.getProperty(key, mResourceBuffer);
87 return QString::fromStdString(buffer->summary()->c_str()); 130 } else if (mLocalBuffer) {
131 return mLocalMapper.getProperty(key, mLocalBuffer);
88 } 132 }
89 return QVariant(); 133 return QVariant();
90 } 134 }
91 135
92 //Data is read-only 136 Akonadi2::Domain::Buffer::Event const *mLocalBuffer;
93 DummyEvent const *buffer; 137 DummyEvent const *mResourceBuffer;
138
139 PropertyMapper<Akonadi2::Domain::Buffer::Event> mLocalMapper;
140 PropertyMapper<DummyEvent> mResourceMapper;
94 141
95 //Keep query alive so values remain valid 142 //Keep query alive so values remain valid
96 QSharedPointer<Akonadi2::Storage> storage; 143 QSharedPointer<Akonadi2::Storage> storage;
@@ -140,6 +187,7 @@ void DummyResourceFacade::load(const Akonadi2::Query &query, const std::function
140 qDebug() << "load called"; 187 qDebug() << "load called";
141 188
142 synchronizeResource([=]() { 189 synchronizeResource([=]() {
190 qDebug() << "sync complete";
143 //Now that the sync is complete we can execute the query 191 //Now that the sync is complete we can execute the query
144 const auto preparedQuery = prepareQuery(query); 192 const auto preparedQuery = prepareQuery(query);
145 193
@@ -151,15 +199,19 @@ void DummyResourceFacade::load(const Akonadi2::Query &query, const std::function
151 storage->startTransaction(Akonadi2::Storage::ReadOnly); 199 storage->startTransaction(Akonadi2::Storage::ReadOnly);
152 //Because we have no indexes yet, we always do a full scan 200 //Because we have no indexes yet, we always do a full scan
153 storage->scan("", [=](void *keyValue, int keySize, void *dataValue, int dataSize) -> bool { 201 storage->scan("", [=](void *keyValue, int keySize, void *dataValue, int dataSize) -> bool {
154 //TODO read the three buffers
155 qDebug() << QString::fromStdString(std::string(static_cast<char*>(keyValue), keySize)); 202 qDebug() << QString::fromStdString(std::string(static_cast<char*>(keyValue), keySize));
156 auto eventBuffer = GetDummyEvent(dataValue); 203 auto buffer = Akonadi2::GetEntityBuffer(dataValue);
157 if (preparedQuery && preparedQuery(std::string(static_cast<char*>(keyValue), keySize), eventBuffer)) { 204 auto resourceBuffer = GetDummyEvent(buffer->resource());
158 //TODO set proper revision 205 auto metadataBuffer = Akonadi2::GetMetadata(buffer->resource());
159 qint64 revision = 0; 206 auto localBuffer = Akonadi2::Domain::Buffer::GetEvent(buffer->local());
160 auto event = QSharedPointer<DummyEventAdaptor>::create("org.kde.dummy", QString::fromUtf8(static_cast<char*>(keyValue), keySize), revision); 207 //We probably only want to create all buffers after the scan
161 event->buffer = eventBuffer; 208 if (preparedQuery && preparedQuery(std::string(static_cast<char*>(keyValue), keySize), resourceBuffer)) {
162 event->storage = storage; 209 qint64 revision = metadataBuffer->revision();
210 auto adaptor = QSharedPointer<DummyEventAdaptor>::create();
211 adaptor->mLocalBuffer = localBuffer;
212 adaptor->mResourceBuffer = resourceBuffer;
213 adaptor->storage = storage;
214 auto event = QSharedPointer<Akonadi2::Domain::Event>::create("org.kde.dummy", QString::fromUtf8(static_cast<char*>(keyValue), keySize), revision, adaptor);
163 resultCallback(event); 215 resultCallback(event);
164 } 216 }
165 return true; 217 return true;