diff options
Diffstat (limited to 'examples/maildirresource/maildirresource.cpp')
-rw-r--r-- | examples/maildirresource/maildirresource.cpp | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/examples/maildirresource/maildirresource.cpp b/examples/maildirresource/maildirresource.cpp index d0b663b..8333f76 100644 --- a/examples/maildirresource/maildirresource.cpp +++ b/examples/maildirresource/maildirresource.cpp | |||
@@ -63,6 +63,22 @@ MaildirResource::MaildirResource(const QByteArray &instanceIdentifier, const QSh | |||
63 | Trace() << "Started maildir resource for maildir: " << mMaildirPath; | 63 | Trace() << "Started maildir resource for maildir: " << mMaildirPath; |
64 | } | 64 | } |
65 | 65 | ||
66 | void MaildirResource::recordRemoteId(const QByteArray &bufferType, const QByteArray &localId, const QByteArray &remoteId, Akonadi2::Storage::Transaction &transaction) | ||
67 | { | ||
68 | Index index("rid.mapping." + bufferType, transaction); | ||
69 | Index localIndex("localid.mapping." + bufferType, transaction); | ||
70 | index.add(remoteId, localId); | ||
71 | localIndex.add(localId, remoteId); | ||
72 | } | ||
73 | |||
74 | void MaildirResource::removeRemoteId(const QByteArray &bufferType, const QByteArray &localId, const QByteArray &remoteId, Akonadi2::Storage::Transaction &transaction) | ||
75 | { | ||
76 | Index index("rid.mapping." + bufferType, transaction); | ||
77 | Index localIndex("localid.mapping." + bufferType, transaction); | ||
78 | index.remove(remoteId, localId); | ||
79 | localIndex.remove(localId, remoteId); | ||
80 | } | ||
81 | |||
66 | QString MaildirResource::resolveRemoteId(const QByteArray &bufferType, const QString &remoteId, Akonadi2::Storage::Transaction &transaction) | 82 | QString MaildirResource::resolveRemoteId(const QByteArray &bufferType, const QString &remoteId, Akonadi2::Storage::Transaction &transaction) |
67 | { | 83 | { |
68 | //Lookup local id for remote id, or insert a new pair otherwise | 84 | //Lookup local id for remote id, or insert a new pair otherwise |
@@ -332,17 +348,62 @@ KAsync::Job<void> MaildirResource::synchronizeWithSource() | |||
332 | { | 348 | { |
333 | Log() << " Synchronizing"; | 349 | Log() << " Synchronizing"; |
334 | return KAsync::start<void>([this]() { | 350 | return KAsync::start<void>([this]() { |
351 | //Changereplay would deadlock otherwise when trying to open the synchronization store | ||
352 | enableChangeReplay(false); | ||
335 | auto transaction = Akonadi2::Storage(Akonadi2::storageLocation(), mResourceInstanceIdentifier, Akonadi2::Storage::ReadOnly).createTransaction(Akonadi2::Storage::ReadOnly); | 353 | auto transaction = Akonadi2::Storage(Akonadi2::storageLocation(), mResourceInstanceIdentifier, Akonadi2::Storage::ReadOnly).createTransaction(Akonadi2::Storage::ReadOnly); |
336 | synchronizeFolders(transaction); | 354 | synchronizeFolders(transaction); |
337 | for (const auto &folder : listAvailableFolders()) { | 355 | for (const auto &folder : listAvailableFolders()) { |
338 | synchronizeMails(transaction, folder); | 356 | synchronizeMails(transaction, folder); |
339 | } | 357 | } |
358 | Log() << "Done Synchronizing"; | ||
359 | enableChangeReplay(true); | ||
340 | }); | 360 | }); |
341 | } | 361 | } |
342 | 362 | ||
343 | KAsync::Job<void> MaildirResource::replay(const QByteArray &type, const QByteArray &key, const QByteArray &value) | 363 | KAsync::Job<void> MaildirResource::replay(const QByteArray &type, const QByteArray &key, const QByteArray &value) |
344 | { | 364 | { |
345 | Trace() << "Replaying " << key; | 365 | //This results in a deadlock during sync |
366 | Akonadi2::Storage store(Akonadi2::storageLocation(), mResourceInstanceIdentifier + ".synchronization", Akonadi2::Storage::ReadWrite); | ||
367 | auto synchronizationTransaction = store.createTransaction(Akonadi2::Storage::ReadWrite); | ||
368 | const auto uid = Akonadi2::Storage::uidFromKey(key); | ||
369 | const auto remoteId = resolveLocalId(type, uid, synchronizationTransaction); | ||
370 | |||
371 | Trace() << "Replaying " << key << type; | ||
372 | if (type == ENTITY_TYPE_FOLDER) { | ||
373 | Akonadi2::EntityBuffer buffer(value.data(), value.size()); | ||
374 | const Akonadi2::Entity &entity = buffer.entity(); | ||
375 | const auto metadataBuffer = Akonadi2::EntityBuffer::readBuffer<Akonadi2::Metadata>(entity.metadata()); | ||
376 | const qint64 revision = metadataBuffer ? metadataBuffer->revision() : -1; | ||
377 | const auto operation = metadataBuffer ? metadataBuffer->operation() : Akonadi2::Operation_Creation; | ||
378 | if (operation == Akonadi2::Operation_Creation) { | ||
379 | //FIXME: This check only works for new entities | ||
380 | //Figure out wether we have replayed that revision already to the source | ||
381 | if (!remoteId.isEmpty()) { | ||
382 | Trace() << "Change is coming from the source"; | ||
383 | return KAsync::null<void>(); | ||
384 | } | ||
385 | const Akonadi2::ApplicationDomain::Folder folder(mResourceInstanceIdentifier, Akonadi2::Storage::uidFromKey(key), revision, mFolderAdaptorFactory->createAdaptor(entity)); | ||
386 | auto folderName = folder.getProperty("name").toString(); | ||
387 | //TODO handle non toplevel folders | ||
388 | auto path = mMaildirPath + "/" + folderName; | ||
389 | Trace() << "Creating a new folder: " << path; | ||
390 | KPIM::Maildir maildir(path, false); | ||
391 | maildir.create(); | ||
392 | recordRemoteId(ENTITY_TYPE_FOLDER, folder.identifier(), path.toUtf8(), synchronizationTransaction); | ||
393 | } else if (operation == Akonadi2::Operation_Removal) { | ||
394 | const auto uid = Akonadi2::Storage::uidFromKey(key); | ||
395 | const auto remoteId = resolveLocalId(ENTITY_TYPE_FOLDER, uid, synchronizationTransaction); | ||
396 | const auto path = remoteId; | ||
397 | Trace() << "Removing a folder: " << path; | ||
398 | KPIM::Maildir maildir(path, false); | ||
399 | maildir.remove(); | ||
400 | removeRemoteId(ENTITY_TYPE_FOLDER, uid, remoteId.toUtf8(), synchronizationTransaction); | ||
401 | } else if (operation == Akonadi2::Operation_Modification) { | ||
402 | Warning() << "Folder modifications are not implemented"; | ||
403 | } else { | ||
404 | Warning() << "Unkown operation" << operation; | ||
405 | } | ||
406 | } | ||
346 | return KAsync::null<void>(); | 407 | return KAsync::null<void>(); |
347 | } | 408 | } |
348 | 409 | ||