summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2015-12-01 11:10:37 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2015-12-01 11:10:37 +0100
commit44edbee0f0b2fcf13e2ee388a90a8dd1f84a329e (patch)
tree71d265b2bce5a15981976e334ed182fa6d37c45f
parent377c86144221ffc5b49bdaa9b8dcc3507fe4a50f (diff)
downloadsink-44edbee0f0b2fcf13e2ee388a90a8dd1f84a329e.tar.gz
sink-44edbee0f0b2fcf13e2ee388a90a8dd1f84a329e.zip
Resolve remoteIds during sync
Remote id's need to be resolved while syncing any references. This is done by the synchronizer by consulting the rid to entity id mapping. If the referenced entity doesn't exist yet we create a local id anyways, that we then need to pick up once the actual entity arrives.
-rw-r--r--common/commands/createentity.fbs1
-rw-r--r--common/index.cpp13
-rw-r--r--common/index.h1
-rw-r--r--common/pipeline.cpp9
-rw-r--r--common/resourceaccess.cpp2
-rw-r--r--examples/dummyresource/dummystore.cpp7
-rw-r--r--examples/dummyresource/resourcefactory.cpp22
-rw-r--r--examples/dummyresource/resourcefactory.h1
-rw-r--r--tests/dummyresourcebenchmark.cpp3
9 files changed, 53 insertions, 6 deletions
diff --git a/common/commands/createentity.fbs b/common/commands/createentity.fbs
index 23eeff9..a5bc95c 100644
--- a/common/commands/createentity.fbs
+++ b/common/commands/createentity.fbs
@@ -1,6 +1,7 @@
1namespace Akonadi2.Commands; 1namespace Akonadi2.Commands;
2 2
3table CreateEntity { 3table CreateEntity {
4 entityId: string;
4 domainType: string; 5 domainType: string;
5 delta: [ubyte]; 6 delta: [ubyte];
6} 7}
diff --git a/common/index.cpp b/common/index.cpp
index 2fc0fe3..f4de93c 100644
--- a/common/index.cpp
+++ b/common/index.cpp
@@ -38,3 +38,16 @@ void Index::lookup(const QByteArray &key, const std::function<void(const QByteAr
38 ); 38 );
39} 39}
40 40
41QByteArray Index::lookup(const QByteArray &key)
42{
43 QByteArray result;
44 lookup(key,
45 [&result](const QByteArray &value) {
46 result = value;
47 },
48 [](const Index::Error &error) {
49 qDebug() << "Error while retrieving value" << error.message;
50 });
51 return result;
52}
53
diff --git a/common/index.h b/common/index.h
index 0ca32af..6b06d26 100644
--- a/common/index.h
+++ b/common/index.h
@@ -33,6 +33,7 @@ public:
33 33
34 void lookup(const QByteArray &key, const std::function<void(const QByteArray &value)> &resultHandler, 34 void lookup(const QByteArray &key, const std::function<void(const QByteArray &value)> &resultHandler,
35 const std::function<void(const Error &error)> &errorHandler); 35 const std::function<void(const Error &error)> &errorHandler);
36 QByteArray lookup(const QByteArray &key);
36 37
37private: 38private:
38 Q_DISABLE_COPY(Index); 39 Q_DISABLE_COPY(Index);
diff --git a/common/pipeline.cpp b/common/pipeline.cpp
index 0ce478b..16d8329 100644
--- a/common/pipeline.cpp
+++ b/common/pipeline.cpp
@@ -150,7 +150,14 @@ KAsync::Job<qint64> Pipeline::newEntity(void const *command, size_t size)
150 return KAsync::error<qint64>(0); 150 return KAsync::error<qint64>(0);
151 } 151 }
152 152
153 const auto key = QUuid::createUuid().toString().toUtf8(); 153 QByteArray key;
154 if (createEntity->entityId()) {
155 key = QByteArray(reinterpret_cast<char const*>(createEntity->entityId()->Data()), createEntity->entityId()->size());
156 }
157 if (key.isEmpty()) {
158 key = QUuid::createUuid().toString().toUtf8();
159 }
160 Q_ASSERT(!key.isEmpty());
154 const qint64 newRevision = Akonadi2::Storage::maxRevision(d->transaction) + 1; 161 const qint64 newRevision = Akonadi2::Storage::maxRevision(d->transaction) + 1;
155 162
156 //Add metadata buffer 163 //Add metadata buffer
diff --git a/common/resourceaccess.cpp b/common/resourceaccess.cpp
index be25533..8988032 100644
--- a/common/resourceaccess.cpp
+++ b/common/resourceaccess.cpp
@@ -296,7 +296,7 @@ KAsync::Job<void> ResourceAccess::sendCreateCommand(const QByteArray &resourceBu
296 //This is the resource buffer type and not the domain type 296 //This is the resource buffer type and not the domain type
297 auto type = fbb.CreateString(resourceBufferType.constData()); 297 auto type = fbb.CreateString(resourceBufferType.constData());
298 auto delta = Akonadi2::EntityBuffer::appendAsVector(fbb, buffer.constData(), buffer.size()); 298 auto delta = Akonadi2::EntityBuffer::appendAsVector(fbb, buffer.constData(), buffer.size());
299 auto location = Akonadi2::Commands::CreateCreateEntity(fbb, type, delta); 299 auto location = Akonadi2::Commands::CreateCreateEntity(fbb, 0, type, delta);
300 Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location); 300 Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location);
301 open(); 301 open();
302 return sendCommand(Akonadi2::Commands::CreateEntityCommand, fbb); 302 return sendCommand(Akonadi2::Commands::CreateEntityCommand, fbb);
diff --git a/examples/dummyresource/dummystore.cpp b/examples/dummyresource/dummystore.cpp
index 458695f..8592a30 100644
--- a/examples/dummyresource/dummystore.cpp
+++ b/examples/dummyresource/dummystore.cpp
@@ -64,9 +64,14 @@ QMap<QString, QMap<QString, QVariant> > populateMails()
64QMap<QString, QMap<QString, QVariant> > populateFolders() 64QMap<QString, QMap<QString, QVariant> > populateFolders()
65{ 65{
66 QMap<QString, QMap<QString, QVariant>> content; 66 QMap<QString, QMap<QString, QVariant>> content;
67 for (int i = 0; i < 5; i++) { 67 int i = 0;
68 for (i = 0; i < 5; i++) {
68 content.insert(QString("key%1").arg(i), createFolder(i)); 69 content.insert(QString("key%1").arg(i), createFolder(i));
69 } 70 }
71 i++;
72 auto folder = createFolder(i);
73 folder.insert("parent", "key0");
74 content.insert(QString("key%1").arg(i), folder);
70 return content; 75 return content;
71} 76}
72 77
diff --git a/examples/dummyresource/resourcefactory.cpp b/examples/dummyresource/resourcefactory.cpp
index e524c3f..8dae749 100644
--- a/examples/dummyresource/resourcefactory.cpp
+++ b/examples/dummyresource/resourcefactory.cpp
@@ -36,6 +36,7 @@
36#include "definitions.h" 36#include "definitions.h"
37#include "facadefactory.h" 37#include "facadefactory.h"
38#include <QDate> 38#include <QDate>
39#include <QUuid>
39 40
40//This is the resources entity type, and not the domain type 41//This is the resources entity type, and not the domain type
41#define ENTITY_TYPE_EVENT "event" 42#define ENTITY_TYPE_EVENT "event"
@@ -182,6 +183,19 @@ void DummyResource::createMail(const QByteArray &ridBuffer, const QMap<QString,
182 Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize()); 183 Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize());
183} 184}
184 185
186QString DummyResource::resolveRemoteId(const QString &remoteId)
187{
188 //Lookup local id for remote id, or insert a new pair otherwise
189 Akonadi2::Storage store(Akonadi2::storageLocation(), mResourceInstanceIdentifier + ".synchronization", Akonadi2::Storage::ReadWrite);
190 auto transaction = store.createTransaction(Akonadi2::Storage::ReadWrite);
191 QByteArray akonadiId = Index("rid.mapping", transaction).lookup(remoteId.toLatin1());
192 if (akonadiId.isEmpty()) {
193 akonadiId = QUuid::createUuid().toString().toUtf8();
194 Index("rid.mapping", transaction).add(remoteId.toLatin1(), akonadiId);
195 }
196 return akonadiId;
197}
198
185void DummyResource::createFolder(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) 199void DummyResource::createFolder(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb)
186{ 200{
187 //Map the source format to the buffer format (which happens to be an exact copy here) 201 //Map the source format to the buffer format (which happens to be an exact copy here)
@@ -190,7 +204,8 @@ void DummyResource::createFolder(const QByteArray &ridBuffer, const QMap<QString
190 bool hasParent = false; 204 bool hasParent = false;
191 if (!data.value("parent").toString().isEmpty()) { 205 if (!data.value("parent").toString().isEmpty()) {
192 hasParent = true; 206 hasParent = true;
193 parent = m_fbb.CreateString(data.value("parent").toString().toStdString()); 207 auto akonadiId = resolveRemoteId(data.value("parent").toString());
208 parent = m_fbb.CreateString(akonadiId.toStdString());
194 } 209 }
195 210
196 auto builder = Akonadi2::ApplicationDomain::Buffer::FolderBuilder(m_fbb); 211 auto builder = Akonadi2::ApplicationDomain::Buffer::FolderBuilder(m_fbb);
@@ -222,11 +237,14 @@ void DummyResource::synchronize(const QString &bufferType, const QMap<QString, Q
222 flatbuffers::FlatBufferBuilder entityFbb; 237 flatbuffers::FlatBufferBuilder entityFbb;
223 createEntity(it.key().toUtf8(), it.value(), entityFbb); 238 createEntity(it.key().toUtf8(), it.value(), entityFbb);
224 239
240 auto akonadiId = resolveRemoteId(it.key());
241
225 flatbuffers::FlatBufferBuilder fbb; 242 flatbuffers::FlatBufferBuilder fbb;
226 //This is the resource type and not the domain type 243 //This is the resource type and not the domain type
244 auto entityId = fbb.CreateString(akonadiId.toStdString());
227 auto type = fbb.CreateString(bufferType.toStdString()); 245 auto type = fbb.CreateString(bufferType.toStdString());
228 auto delta = Akonadi2::EntityBuffer::appendAsVector(fbb, entityFbb.GetBufferPointer(), entityFbb.GetSize()); 246 auto delta = Akonadi2::EntityBuffer::appendAsVector(fbb, entityFbb.GetBufferPointer(), entityFbb.GetSize());
229 auto location = Akonadi2::Commands::CreateCreateEntity(fbb, type, delta); 247 auto location = Akonadi2::Commands::CreateCreateEntity(fbb, entityId, type, delta);
230 Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location); 248 Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location);
231 249
232 enqueueCommand(mSynchronizerQueue, Akonadi2::Commands::CreateEntityCommand, QByteArray::fromRawData(reinterpret_cast<char const *>(fbb.GetBufferPointer()), fbb.GetSize())); 250 enqueueCommand(mSynchronizerQueue, Akonadi2::Commands::CreateEntityCommand, QByteArray::fromRawData(reinterpret_cast<char const *>(fbb.GetBufferPointer()), fbb.GetSize()));
diff --git a/examples/dummyresource/resourcefactory.h b/examples/dummyresource/resourcefactory.h
index 67681ae..f7882ca 100644
--- a/examples/dummyresource/resourcefactory.h
+++ b/examples/dummyresource/resourcefactory.h
@@ -36,6 +36,7 @@ public:
36 KAsync::Job<void> synchronizeWithSource() Q_DECL_OVERRIDE; 36 KAsync::Job<void> synchronizeWithSource() Q_DECL_OVERRIDE;
37 static void removeFromDisk(const QByteArray &instanceIdentifier); 37 static void removeFromDisk(const QByteArray &instanceIdentifier);
38private: 38private:
39 QString resolveRemoteId(const QString &remoteId);
39 void createEvent(const QByteArray &rid, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb); 40 void createEvent(const QByteArray &rid, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb);
40 void createMail(const QByteArray &rid, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb); 41 void createMail(const QByteArray &rid, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb);
41 void createFolder(const QByteArray &rid, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb); 42 void createFolder(const QByteArray &rid, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb);
diff --git a/tests/dummyresourcebenchmark.cpp b/tests/dummyresourcebenchmark.cpp
index 6eaf065..94a4e72 100644
--- a/tests/dummyresourcebenchmark.cpp
+++ b/tests/dummyresourcebenchmark.cpp
@@ -188,10 +188,11 @@ private Q_SLOTS:
188 static flatbuffers::FlatBufferBuilder fbb; 188 static flatbuffers::FlatBufferBuilder fbb;
189 fbb.Clear(); 189 fbb.Clear();
190 //This is the resource buffer type and not the domain type 190 //This is the resource buffer type and not the domain type
191 auto entityId = fbb.CreateString("");
191 auto type = fbb.CreateString("event"); 192 auto type = fbb.CreateString("event");
192 // auto delta = fbb.CreateVector<uint8_t>(entityFbb.GetBufferPointer(), entityFbb.GetSize()); 193 // auto delta = fbb.CreateVector<uint8_t>(entityFbb.GetBufferPointer(), entityFbb.GetSize());
193 auto delta = Akonadi2::EntityBuffer::appendAsVector(fbb, entityFbb.GetBufferPointer(), entityFbb.GetSize()); 194 auto delta = Akonadi2::EntityBuffer::appendAsVector(fbb, entityFbb.GetBufferPointer(), entityFbb.GetSize());
194 auto location = Akonadi2::Commands::CreateCreateEntity(fbb, type, delta); 195 auto location = Akonadi2::Commands::CreateCreateEntity(fbb, entityId, type, delta);
195 Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location); 196 Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location);
196 } 197 }
197 } 198 }