summaryrefslogtreecommitdiffstats
path: root/examples/dummyresource/resourcefactory.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2015-12-01 15:48:54 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2015-12-01 15:48:54 +0100
commitae7cc26c8350b427870f83687f83184c2c211250 (patch)
treed0b6e2d0e387858f97a673ade79ba4659fca1321 /examples/dummyresource/resourcefactory.cpp
parentd5606030b5eb6f7ec92bc9b9d4218692af43a628 (diff)
downloadsink-ae7cc26c8350b427870f83687f83184c2c211250.tar.gz
sink-ae7cc26c8350b427870f83687f83184c2c211250.zip
Synchronizer: One transaction per sync, and check if entity already
exists. With this we no longer repeatedly create entities on every sync.
Diffstat (limited to 'examples/dummyresource/resourcefactory.cpp')
-rw-r--r--examples/dummyresource/resourcefactory.cpp59
1 files changed, 30 insertions, 29 deletions
diff --git a/examples/dummyresource/resourcefactory.cpp b/examples/dummyresource/resourcefactory.cpp
index 73b2eb5..9a577a0 100644
--- a/examples/dummyresource/resourcefactory.cpp
+++ b/examples/dummyresource/resourcefactory.cpp
@@ -141,7 +141,7 @@ DummyResource::DummyResource(const QByteArray &instanceIdentifier, const QShared
141 } 141 }
142} 142}
143 143
144void DummyResource::createEvent(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) 144void DummyResource::createEvent(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &transaction)
145{ 145{
146 //Map the source format to the buffer format (which happens to be an exact copy here) 146 //Map the source format to the buffer format (which happens to be an exact copy here)
147 auto summary = m_fbb.CreateString(data.value("summary").toString().toStdString()); 147 auto summary = m_fbb.CreateString(data.value("summary").toString().toStdString());
@@ -160,7 +160,7 @@ void DummyResource::createEvent(const QByteArray &ridBuffer, const QMap<QString,
160 Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize(), 0, 0); 160 Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize(), 0, 0);
161} 161}
162 162
163void DummyResource::createMail(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) 163void DummyResource::createMail(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &transaction)
164{ 164{
165 //Map the source format to the buffer format (which happens to be an exact copy here) 165 //Map the source format to the buffer format (which happens to be an exact copy here)
166 auto subject = m_fbb.CreateString(data.value("subject").toString().toStdString()); 166 auto subject = m_fbb.CreateString(data.value("subject").toString().toStdString());
@@ -182,11 +182,9 @@ void DummyResource::createMail(const QByteArray &ridBuffer, const QMap<QString,
182 Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize()); 182 Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize());
183} 183}
184 184
185QString DummyResource::resolveRemoteId(const QString &remoteId) 185QString DummyResource::resolveRemoteId(const QString &remoteId, Akonadi2::Storage::Transaction &transaction)
186{ 186{
187 //Lookup local id for remote id, or insert a new pair otherwise 187 //Lookup local id for remote id, or insert a new pair otherwise
188 Akonadi2::Storage store(Akonadi2::storageLocation(), mResourceInstanceIdentifier + ".synchronization", Akonadi2::Storage::ReadWrite);
189 auto transaction = store.createTransaction(Akonadi2::Storage::ReadWrite);
190 QByteArray akonadiId = Index("rid.mapping", transaction).lookup(remoteId.toLatin1()); 188 QByteArray akonadiId = Index("rid.mapping", transaction).lookup(remoteId.toLatin1());
191 if (akonadiId.isEmpty()) { 189 if (akonadiId.isEmpty()) {
192 akonadiId = QUuid::createUuid().toString().toUtf8(); 190 akonadiId = QUuid::createUuid().toString().toUtf8();
@@ -195,7 +193,7 @@ QString DummyResource::resolveRemoteId(const QString &remoteId)
195 return akonadiId; 193 return akonadiId;
196} 194}
197 195
198void DummyResource::createFolder(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) 196void DummyResource::createFolder(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &transaction)
199{ 197{
200 //Map the source format to the buffer format (which happens to be an exact copy here) 198 //Map the source format to the buffer format (which happens to be an exact copy here)
201 auto name = m_fbb.CreateString(data.value("name").toString().toStdString()); 199 auto name = m_fbb.CreateString(data.value("name").toString().toStdString());
@@ -203,7 +201,7 @@ void DummyResource::createFolder(const QByteArray &ridBuffer, const QMap<QString
203 bool hasParent = false; 201 bool hasParent = false;
204 if (!data.value("parent").toString().isEmpty()) { 202 if (!data.value("parent").toString().isEmpty()) {
205 hasParent = true; 203 hasParent = true;
206 auto akonadiId = resolveRemoteId(data.value("parent").toString()); 204 auto akonadiId = resolveRemoteId(data.value("parent").toString(), transaction);
207 parent = m_fbb.CreateString(akonadiId.toStdString()); 205 parent = m_fbb.CreateString(akonadiId.toStdString());
208 } 206 }
209 207
@@ -217,26 +215,27 @@ void DummyResource::createFolder(const QByteArray &ridBuffer, const QMap<QString
217 Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize()); 215 Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize());
218} 216}
219 217
220void DummyResource::synchronize(const QString &bufferType, const QMap<QString, QMap<QString, QVariant> > &data, Akonadi2::Storage::Transaction &transaction, std::function<void(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb)> createEntity) 218void DummyResource::synchronize(const QString &bufferType, const QMap<QString, QMap<QString, QVariant> > &data, Akonadi2::Storage::Transaction &transaction, std::function<void(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &)> createEntity)
221{ 219{
222 Index uidIndex("index.uid", transaction); 220 Akonadi2::Storage store(Akonadi2::storageLocation(), mResourceInstanceIdentifier + ".synchronization", Akonadi2::Storage::ReadWrite);
221 auto synchronizationTransaction = store.createTransaction(Akonadi2::Storage::ReadWrite);
222 Index ridMapping("rid.mapping", synchronizationTransaction);
223 for (auto it = data.constBegin(); it != data.constEnd(); it++) { 223 for (auto it = data.constBegin(); it != data.constEnd(); it++) {
224 bool isNew = true; 224 const auto remoteId = it.key().toUtf8();
225 uidIndex.lookup(it.key().toLatin1(), [&](const QByteArray &value) { 225 auto akonadiId = resolveRemoteId(remoteId, synchronizationTransaction);
226 isNew = false; 226
227 }, 227 bool found = false;
228 [](const Index::Error &error) { 228 transaction.openDatabase(bufferType.toUtf8() + ".main").scan(akonadiId.toUtf8(), [&found](const QByteArray &, const QByteArray &) -> bool {
229 if (error.code != Index::IndexNotAvailable) { 229 found = true;
230 Warning() << "Error in uid index: " << error.message; 230 return false;
231 } 231 }, [this](const Akonadi2::Storage::Error &error) {
232 }); 232 }, true);
233 if (isNew) { 233
234 if (!found) { //A new entity
234 m_fbb.Clear(); 235 m_fbb.Clear();
235 236
236 flatbuffers::FlatBufferBuilder entityFbb; 237 flatbuffers::FlatBufferBuilder entityFbb;
237 createEntity(it.key().toUtf8(), it.value(), entityFbb); 238 createEntity(remoteId, it.value(), entityFbb, synchronizationTransaction);
238
239 auto akonadiId = resolveRemoteId(it.key());
240 239
241 flatbuffers::FlatBufferBuilder fbb; 240 flatbuffers::FlatBufferBuilder fbb;
242 //This is the resource type and not the domain type 241 //This is the resource type and not the domain type
@@ -246,8 +245,10 @@ void DummyResource::synchronize(const QString &bufferType, const QMap<QString, Q
246 auto location = Akonadi2::Commands::CreateCreateEntity(fbb, entityId, type, delta); 245 auto location = Akonadi2::Commands::CreateCreateEntity(fbb, entityId, type, delta);
247 Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location); 246 Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location);
248 247
248 Trace() << "Found a new entity: " << remoteId;
249 enqueueCommand(mSynchronizerQueue, Akonadi2::Commands::CreateEntityCommand, QByteArray::fromRawData(reinterpret_cast<char const *>(fbb.GetBufferPointer()), fbb.GetSize())); 249 enqueueCommand(mSynchronizerQueue, Akonadi2::Commands::CreateEntityCommand, QByteArray::fromRawData(reinterpret_cast<char const *>(fbb.GetBufferPointer()), fbb.GetSize()));
250 } else { //modification 250 } else { //modification
251 Trace() << "Found a modified entity: " << remoteId;
251 //TODO diff and create modification if necessary 252 //TODO diff and create modification if necessary
252 } 253 }
253 } 254 }
@@ -260,14 +261,14 @@ KAsync::Job<void> DummyResource::synchronizeWithSource()
260 return KAsync::start<void>([this](KAsync::Future<void> &f) { 261 return KAsync::start<void>([this](KAsync::Future<void> &f) {
261 auto transaction = Akonadi2::Storage(Akonadi2::storageLocation(), mResourceInstanceIdentifier, Akonadi2::Storage::ReadOnly).createTransaction(Akonadi2::Storage::ReadOnly); 262 auto transaction = Akonadi2::Storage(Akonadi2::storageLocation(), mResourceInstanceIdentifier, Akonadi2::Storage::ReadOnly).createTransaction(Akonadi2::Storage::ReadOnly);
262 263
263 synchronize(ENTITY_TYPE_EVENT, DummyStore::instance().events(), transaction, [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) { 264 synchronize(ENTITY_TYPE_EVENT, DummyStore::instance().events(), transaction, [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &synchronizationTransaction) {
264 createEvent(ridBuffer, data, entityFbb); 265 createEvent(ridBuffer, data, entityFbb, synchronizationTransaction);
265 }); 266 });
266 synchronize(ENTITY_TYPE_MAIL, DummyStore::instance().mails(), transaction, [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) { 267 synchronize(ENTITY_TYPE_MAIL, DummyStore::instance().mails(), transaction, [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &synchronizationTransaction) {
267 createMail(ridBuffer, data, entityFbb); 268 createMail(ridBuffer, data, entityFbb, synchronizationTransaction);
268 }); 269 });
269 synchronize(ENTITY_TYPE_FOLDER, DummyStore::instance().folders(), transaction, [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) { 270 synchronize(ENTITY_TYPE_FOLDER, DummyStore::instance().folders(), transaction, [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &synchronizationTransaction) {
270 createFolder(ridBuffer, data, entityFbb); 271 createFolder(ridBuffer, data, entityFbb, synchronizationTransaction);
271 }); 272 });
272 273
273 f.setFinished(); 274 f.setFinished();
@@ -277,7 +278,7 @@ KAsync::Job<void> DummyResource::synchronizeWithSource()
277void DummyResource::removeFromDisk(const QByteArray &instanceIdentifier) 278void DummyResource::removeFromDisk(const QByteArray &instanceIdentifier)
278{ 279{
279 GenericResource::removeFromDisk(instanceIdentifier); 280 GenericResource::removeFromDisk(instanceIdentifier);
280 Akonadi2::Storage(Akonadi2::storageLocation(), instanceIdentifier + ".event.index.uid", Akonadi2::Storage::ReadWrite).removeFromDisk(); 281 Akonadi2::Storage(Akonadi2::storageLocation(), instanceIdentifier + ".synchronization", Akonadi2::Storage::ReadWrite).removeFromDisk();
281} 282}
282 283
283DummyResourceFactory::DummyResourceFactory(QObject *parent) 284DummyResourceFactory::DummyResourceFactory(QObject *parent)