diff options
Diffstat (limited to 'dummyresource/resourcefactory.cpp')
-rw-r--r-- | dummyresource/resourcefactory.cpp | 87 |
1 files changed, 80 insertions, 7 deletions
diff --git a/dummyresource/resourcefactory.cpp b/dummyresource/resourcefactory.cpp index bd85b4f..2c43981 100644 --- a/dummyresource/resourcefactory.cpp +++ b/dummyresource/resourcefactory.cpp | |||
@@ -20,22 +20,95 @@ | |||
20 | #include "resourcefactory.h" | 20 | #include "resourcefactory.h" |
21 | #include "facade.h" | 21 | #include "facade.h" |
22 | #include "dummycalendar_generated.h" | 22 | #include "dummycalendar_generated.h" |
23 | #include <QUuid> | ||
24 | |||
25 | static std::string createEvent() | ||
26 | { | ||
27 | static const size_t attachmentSize = 1024*2; // 2KB | ||
28 | static uint8_t rawData[attachmentSize]; | ||
29 | static flatbuffers::FlatBufferBuilder fbb; | ||
30 | fbb.Clear(); | ||
31 | { | ||
32 | auto summary = fbb.CreateString("summary"); | ||
33 | auto data = fbb.CreateUninitializedVector<uint8_t>(attachmentSize); | ||
34 | DummyCalendar::DummyEventBuilder eventBuilder(fbb); | ||
35 | eventBuilder.add_summary(summary); | ||
36 | eventBuilder.add_attachment(data); | ||
37 | auto eventLocation = eventBuilder.Finish(); | ||
38 | DummyCalendar::FinishDummyEventBuffer(fbb, eventLocation); | ||
39 | memcpy((void*)DummyCalendar::GetDummyEvent(fbb.GetBufferPointer())->attachment()->Data(), rawData, attachmentSize); | ||
40 | } | ||
41 | |||
42 | return std::string(reinterpret_cast<const char *>(fbb.GetBufferPointer()), fbb.GetSize()); | ||
43 | } | ||
44 | |||
45 | QMap<QString, QString> populate() | ||
46 | { | ||
47 | QMap<QString, QString> content; | ||
48 | for (int i = 0; i < 2; i++) { | ||
49 | auto event = createEvent(); | ||
50 | content.insert(QString("key%1").arg(i), QString::fromStdString(event)); | ||
51 | } | ||
52 | return content; | ||
53 | } | ||
54 | |||
55 | static QMap<QString, QString> s_dataSource = populate(); | ||
23 | 56 | ||
24 | DummyResource::DummyResource() | 57 | DummyResource::DummyResource() |
25 | : Akonadi2::Resource() | 58 | : Akonadi2::Resource() |
26 | { | 59 | { |
60 | } | ||
27 | 61 | ||
62 | void findByRemoteId(QSharedPointer<Akonadi2::Storage> storage, const QString &rid, std::function<void(void *keyValue, int keySize, void *dataValue, int dataSize)> callback) | ||
63 | { | ||
64 | //TODO lookup in rid index instead of doing a full scan | ||
65 | const std::string ridString = rid.toStdString(); | ||
66 | storage->scan("", [&](void *keyValue, int keySize, void *dataValue, int dataSize) -> bool { | ||
67 | auto eventBuffer = DummyCalendar::GetDummyEvent(dataValue); | ||
68 | if (std::string(eventBuffer->remoteId()->c_str(), eventBuffer->remoteId()->size()) == ridString) { | ||
69 | callback(keyValue, keySize, dataValue, dataSize); | ||
70 | } | ||
71 | return true; | ||
72 | }); | ||
28 | } | 73 | } |
29 | 74 | ||
30 | void DummyResource::synchronizeWithSource(Akonadi2::Pipeline *pipeline) | 75 | void DummyResource::synchronizeWithSource(Akonadi2::Pipeline *pipeline) |
31 | { | 76 | { |
32 | // TODO actually populate the storage with new items | 77 | //TODO use a read-only transaction during the complete sync to sync against a defined revision |
33 | auto builder = DummyCalendar::DummyEventBuilder(m_fbb); | 78 | |
34 | builder .add_summary(m_fbb.CreateString("summary summary!")); | 79 | qDebug() << "synchronize with source"; |
35 | auto buffer = builder.Finish(); | 80 | |
36 | DummyCalendar::FinishDummyEventBuffer(m_fbb, buffer); | 81 | auto storage = QSharedPointer<Akonadi2::Storage>::create(Akonadi2::Store::storageLocation(), "org.kde.dummy"); |
37 | pipeline->newEntity("fakekey", m_fbb); | 82 | for (auto it = s_dataSource.constBegin(); it != s_dataSource.constEnd(); it++) { |
38 | m_fbb.Clear(); | 83 | bool isNew = true; |
84 | if (storage->exists()) { | ||
85 | findByRemoteId(storage, it.key(), [&](void *keyValue, int keySize, void *dataValue, int dataSize) { | ||
86 | isNew = false; | ||
87 | }); | ||
88 | } | ||
89 | |||
90 | if (isNew) { | ||
91 | //TODO: perhaps it would be more convenient to populate the domain types? | ||
92 | //Resource specific parts are not accessible that way, but then we would only have to implement the property mapping in one place | ||
93 | const QByteArray data = it.value().toUtf8(); | ||
94 | auto eventBuffer = DummyCalendar::GetDummyEvent(data.data()); | ||
95 | |||
96 | //Map the source format to the buffer format (which happens to be an exact copy here) | ||
97 | auto builder = DummyCalendar::DummyEventBuilder(m_fbb); | ||
98 | builder.add_summary(m_fbb.CreateString(eventBuffer->summary()->c_str())); | ||
99 | auto buffer = builder.Finish(); | ||
100 | DummyCalendar::FinishDummyEventBuffer(m_fbb, buffer); | ||
101 | |||
102 | //TODO toRFC4122 would probably be more efficient, but results in non-printable keys. | ||
103 | const auto key = QUuid::createUuid().toString().toUtf8(); | ||
104 | //TODO can we really just start populating the buffer and pass the buffer builder? | ||
105 | qDebug() << "new event"; | ||
106 | pipeline->newEntity(key, m_fbb); | ||
107 | } else { //modification | ||
108 | //TODO diff and create modification if necessary | ||
109 | } | ||
110 | } | ||
111 | //TODO find items to remove | ||
39 | } | 112 | } |
40 | 113 | ||
41 | void DummyResource::processCommand(int commandId, const QByteArray &data, uint size, Akonadi2::Pipeline *pipeline) | 114 | void DummyResource::processCommand(int commandId, const QByteArray &data, uint size, Akonadi2::Pipeline *pipeline) |