summaryrefslogtreecommitdiffstats
path: root/dummyresource
diff options
context:
space:
mode:
Diffstat (limited to 'dummyresource')
-rw-r--r--dummyresource/facade.cpp48
-rw-r--r--dummyresource/resourcefactory.cpp94
-rw-r--r--dummyresource/resourcefactory.h3
3 files changed, 99 insertions, 46 deletions
diff --git a/dummyresource/facade.cpp b/dummyresource/facade.cpp
index 458aba6..d3974e9 100644
--- a/dummyresource/facade.cpp
+++ b/dummyresource/facade.cpp
@@ -26,8 +26,9 @@
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" 28#include "event_generated.h"
29#include "entitybuffer_generated.h" 29#include "entity_generated.h"
30#include "metadata_generated.h" 30#include "metadata_generated.h"
31#include <common/entitybuffer.h>
31 32
32using namespace DummyCalendar; 33using namespace DummyCalendar;
33using namespace flatbuffers; 34using namespace flatbuffers;
@@ -199,14 +200,47 @@ void DummyResourceFacade::load(const Akonadi2::Query &query, const std::function
199 storage->startTransaction(Akonadi2::Storage::ReadOnly); 200 storage->startTransaction(Akonadi2::Storage::ReadOnly);
200 //Because we have no indexes yet, we always do a full scan 201 //Because we have no indexes yet, we always do a full scan
201 storage->scan("", [=](void *keyValue, int keySize, void *dataValue, int dataSize) -> bool { 202 storage->scan("", [=](void *keyValue, int keySize, void *dataValue, int dataSize) -> bool {
202 qDebug() << QString::fromStdString(std::string(static_cast<char*>(keyValue), keySize)); 203
203 auto buffer = Akonadi2::GetEntityBuffer(dataValue); 204 //Skip internals
204 auto resourceBuffer = GetDummyEvent(buffer->resource()); 205 if (QByteArray::fromRawData(static_cast<char*>(keyValue), keySize).startsWith("__internal")) {
205 auto metadataBuffer = Akonadi2::GetMetadata(buffer->resource()); 206 return true;
206 auto localBuffer = Akonadi2::Domain::Buffer::GetEvent(buffer->local()); 207 }
208
209 //Extract buffers
210 Akonadi2::EntityBuffer buffer(dataValue, dataSize);
211
212 DummyEvent const *resourceBuffer = 0;
213 if (auto resourceData = buffer.resourceBuffer()) {
214 flatbuffers::Verifier verifyer(resourceData->Data(), resourceData->size());
215 if (VerifyDummyEventBuffer(verifyer)) {
216 resourceBuffer = GetDummyEvent(resourceData);
217 }
218 }
219
220 Akonadi2::Metadata const *metadataBuffer = 0;
221 if (auto metadataData = buffer.metadataBuffer()) {
222 flatbuffers::Verifier verifyer(metadataData->Data(), metadataData->size());
223 if (Akonadi2::VerifyMetadataBuffer(verifyer)) {
224 metadataBuffer = Akonadi2::GetMetadata(metadataData);
225 }
226 }
227
228 Akonadi2::Domain::Buffer::Event const *localBuffer = 0;
229 if (auto localData = buffer.localBuffer()) {
230 flatbuffers::Verifier verifyer(localData->Data(), localData->size());
231 if (Akonadi2::Domain::Buffer::VerifyEventBuffer(verifyer)) {
232 localBuffer = Akonadi2::Domain::Buffer::GetEvent(localData);
233 }
234 }
235
236 if (!resourceBuffer || !metadataBuffer) {
237 qWarning() << "invalid buffer " << QString::fromStdString(std::string(static_cast<char*>(keyValue), keySize));
238 return true;
239 }
240
207 //We probably only want to create all buffers after the scan 241 //We probably only want to create all buffers after the scan
208 if (preparedQuery && preparedQuery(std::string(static_cast<char*>(keyValue), keySize), resourceBuffer)) { 242 if (preparedQuery && preparedQuery(std::string(static_cast<char*>(keyValue), keySize), resourceBuffer)) {
209 qint64 revision = metadataBuffer->revision(); 243 qint64 revision = metadataBuffer ? metadataBuffer->revision() : -1;
210 auto adaptor = QSharedPointer<DummyEventAdaptor>::create(); 244 auto adaptor = QSharedPointer<DummyEventAdaptor>::create();
211 adaptor->mLocalBuffer = localBuffer; 245 adaptor->mLocalBuffer = localBuffer;
212 adaptor->mResourceBuffer = resourceBuffer; 246 adaptor->mResourceBuffer = resourceBuffer;
diff --git a/dummyresource/resourcefactory.cpp b/dummyresource/resourcefactory.cpp
index 6b93985..c9e4d7a 100644
--- a/dummyresource/resourcefactory.cpp
+++ b/dummyresource/resourcefactory.cpp
@@ -19,7 +19,9 @@
19 19
20#include "resourcefactory.h" 20#include "resourcefactory.h"
21#include "facade.h" 21#include "facade.h"
22#include "entitybuffer.h"
22#include "dummycalendar_generated.h" 23#include "dummycalendar_generated.h"
24#include "metadata_generated.h"
23#include <QUuid> 25#include <QUuid>
24 26
25static std::string createEvent() 27static std::string createEvent()
@@ -64,51 +66,67 @@ void findByRemoteId(QSharedPointer<Akonadi2::Storage> storage, const QString &ri
64 //TODO lookup in rid index instead of doing a full scan 66 //TODO lookup in rid index instead of doing a full scan
65 const std::string ridString = rid.toStdString(); 67 const std::string ridString = rid.toStdString();
66 storage->scan("", [&](void *keyValue, int keySize, void *dataValue, int dataSize) -> bool { 68 storage->scan("", [&](void *keyValue, int keySize, void *dataValue, int dataSize) -> bool {
67 auto eventBuffer = DummyCalendar::GetDummyEvent(dataValue); 69 if (QByteArray::fromRawData(static_cast<char*>(keyValue), keySize).startsWith("__internal")) {
68 if (std::string(eventBuffer->remoteId()->c_str(), eventBuffer->remoteId()->size()) == ridString) { 70 return true;
69 callback(keyValue, keySize, dataValue, dataSize);
70 } 71 }
72
73 Akonadi2::EntityBuffer::extractResourceBuffer(dataValue, dataSize, [&](const flatbuffers::Vector<uint8_t> *buffer) {
74 flatbuffers::Verifier verifier(buffer->Data(), buffer->size());
75 if (DummyCalendar::VerifyDummyEventBuffer(verifier)) {
76 DummyCalendar::DummyEvent const *resourceBuffer = DummyCalendar::GetDummyEvent(buffer->Data());
77 if (resourceBuffer && resourceBuffer->remoteId()) {
78 if (std::string(resourceBuffer->remoteId()->c_str(), resourceBuffer->remoteId()->size()) == ridString) {
79 callback(keyValue, keySize, dataValue, dataSize);
80 }
81 }
82 }
83 });
71 return true; 84 return true;
72 }); 85 });
73} 86}
74 87
75void DummyResource::synchronizeWithSource(Akonadi2::Pipeline *pipeline) 88Async::Job<void> DummyResource::synchronizeWithSource(Akonadi2::Pipeline *pipeline)
76{ 89{
77 //TODO use a read-only transaction during the complete sync to sync against a defined revision 90 return Async::start<void>([this, pipeline](Async::Future<void> &f) {
78 91 //TODO use a read-only transaction during the complete sync to sync against a defined revision
79 qDebug() << "synchronize with source"; 92 auto storage = QSharedPointer<Akonadi2::Storage>::create(Akonadi2::Store::storageLocation(), "org.kde.dummy");
80 93 for (auto it = s_dataSource.constBegin(); it != s_dataSource.constEnd(); it++) {
81 auto storage = QSharedPointer<Akonadi2::Storage>::create(Akonadi2::Store::storageLocation(), "org.kde.dummy"); 94 bool isNew = true;
82 for (auto it = s_dataSource.constBegin(); it != s_dataSource.constEnd(); it++) { 95 if (storage->exists()) {
83 bool isNew = true; 96 findByRemoteId(storage, it.key(), [&](void *keyValue, int keySize, void *dataValue, int dataSize) {
84 if (storage->exists()) { 97 isNew = false;
85 findByRemoteId(storage, it.key(), [&](void *keyValue, int keySize, void *dataValue, int dataSize) { 98 });
86 isNew = false; 99 }
87 }); 100 if (isNew) {
88 } 101 m_fbb.Clear();
89 102
90 if (isNew) { 103 const QByteArray data = it.value().toUtf8();
91 //TODO: perhaps it would be more convenient to populate the domain types? 104 auto eventBuffer = DummyCalendar::GetDummyEvent(data.data());
92 //Resource specific parts are not accessible that way, but then we would only have to implement the property mapping in one place 105
93 const QByteArray data = it.value().toUtf8(); 106 //Map the source format to the buffer format (which happens to be an exact copy here)
94 auto eventBuffer = DummyCalendar::GetDummyEvent(data.data()); 107 auto summary = m_fbb.CreateString(eventBuffer->summary()->c_str());
95 108 auto rid = m_fbb.CreateString(it.key().toStdString().c_str());
96 //Map the source format to the buffer format (which happens to be an exact copy here) 109 auto description = m_fbb.CreateString(it.key().toStdString().c_str());
97 auto builder = DummyCalendar::DummyEventBuilder(m_fbb); 110 static uint8_t rawData[100];
98 builder.add_summary(m_fbb.CreateString(eventBuffer->summary()->c_str())); 111 auto attachment = m_fbb.CreateVector(rawData, 100);
99 auto buffer = builder.Finish(); 112
100 DummyCalendar::FinishDummyEventBuffer(m_fbb, buffer); 113 auto builder = DummyCalendar::DummyEventBuilder(m_fbb);
101 114 builder.add_summary(summary);
102 //TODO toRFC4122 would probably be more efficient, but results in non-printable keys. 115 builder.add_remoteId(rid);
103 const auto key = QUuid::createUuid().toString().toUtf8(); 116 builder.add_description(description);
104 //TODO can we really just start populating the buffer and pass the buffer builder? 117 builder.add_attachment(attachment);
105 qDebug() << "new event"; 118 auto buffer = builder.Finish();
106 pipeline->newEntity(key, m_fbb.GetBufferPointer(), m_fbb.GetSize()); 119 DummyCalendar::FinishDummyEventBuffer(m_fbb, buffer);
107 } else { //modification 120 //TODO toRFC4122 would probably be more efficient, but results in non-printable keys.
108 //TODO diff and create modification if necessary 121 const auto key = QUuid::createUuid().toString().toUtf8();
122 pipeline->newEntity(key, m_fbb.GetBufferPointer(), m_fbb.GetSize());
123 } else { //modification
124 //TODO diff and create modification if necessary
125 }
109 } 126 }
110 } 127 //TODO find items to remove
111 //TODO find items to remove 128 f.setFinished();
129 });
112} 130}
113 131
114void DummyResource::processCommand(int commandId, const QByteArray &data, uint size, Akonadi2::Pipeline *pipeline) 132void DummyResource::processCommand(int commandId, const QByteArray &data, uint size, Akonadi2::Pipeline *pipeline)
diff --git a/dummyresource/resourcefactory.h b/dummyresource/resourcefactory.h
index 807a654..dba674f 100644
--- a/dummyresource/resourcefactory.h
+++ b/dummyresource/resourcefactory.h
@@ -20,6 +20,7 @@
20#pragma once 20#pragma once
21 21
22#include "common/resource.h" 22#include "common/resource.h"
23#include "async/src/async.h"
23 24
24#include <flatbuffers/flatbuffers.h> 25#include <flatbuffers/flatbuffers.h>
25 26
@@ -30,7 +31,7 @@ class DummyResource : public Akonadi2::Resource
30{ 31{
31public: 32public:
32 DummyResource(); 33 DummyResource();
33 void synchronizeWithSource(Akonadi2::Pipeline *pipeline); 34 Async::Job<void> synchronizeWithSource(Akonadi2::Pipeline *pipeline);
34 void processCommand(int commandId, const QByteArray &data, uint size, Akonadi2::Pipeline *pipeline); 35 void processCommand(int commandId, const QByteArray &data, uint size, Akonadi2::Pipeline *pipeline);
35 36
36private: 37private: