summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/maildirresource/libmaildir/maildir.cpp7
-rw-r--r--examples/maildirresource/libmaildir/maildir.h5
-rw-r--r--examples/maildirresource/maildirresource.cpp63
-rw-r--r--examples/maildirresource/maildirresource.h6
4 files changed, 80 insertions, 1 deletions
diff --git a/examples/maildirresource/libmaildir/maildir.cpp b/examples/maildirresource/libmaildir/maildir.cpp
index 67a2d2d..2b0148c 100644
--- a/examples/maildirresource/libmaildir/maildir.cpp
+++ b/examples/maildirresource/libmaildir/maildir.cpp
@@ -332,6 +332,13 @@ bool Maildir::create()
332 return true; 332 return true;
333} 333}
334 334
335bool Maildir::remove()
336{
337 QDir dir(d->path);
338 dir.removeRecursively();
339 return true;
340}
341
335QString Maildir::path() const 342QString Maildir::path() const
336{ 343{
337 return d->path; 344 return d->path;
diff --git a/examples/maildirresource/libmaildir/maildir.h b/examples/maildirresource/libmaildir/maildir.h
index 6853033..f80ba5d 100644
--- a/examples/maildirresource/libmaildir/maildir.h
+++ b/examples/maildirresource/libmaildir/maildir.h
@@ -71,6 +71,11 @@ public:
71 bool create(); 71 bool create();
72 72
73 /** 73 /**
74 * Remove the maildir and everything it contains.
75 */
76 bool remove();
77
78 /**
74 * Returns the path of this maildir. 79 * Returns the path of this maildir.
75 */ 80 */
76 QString path() const; 81 QString path() const;
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
66void 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
74void 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
66QString MaildirResource::resolveRemoteId(const QByteArray &bufferType, const QString &remoteId, Akonadi2::Storage::Transaction &transaction) 82QString 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
343KAsync::Job<void> MaildirResource::replay(const QByteArray &type, const QByteArray &key, const QByteArray &value) 363KAsync::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
diff --git a/examples/maildirresource/maildirresource.h b/examples/maildirresource/maildirresource.h
index eec1e97..e577e18 100644
--- a/examples/maildirresource/maildirresource.h
+++ b/examples/maildirresource/maildirresource.h
@@ -41,6 +41,12 @@ private:
41 KAsync::Job<void> replay(const QByteArray &type, const QByteArray &key, const QByteArray &value) Q_DECL_OVERRIDE; 41 KAsync::Job<void> replay(const QByteArray &type, const QByteArray &key, const QByteArray &value) Q_DECL_OVERRIDE;
42 42
43 /** 43 /**
44 * Records a localId to remoteId mapping
45 */
46 void recordRemoteId(const QByteArray &bufferType, const QByteArray &localId, const QByteArray &remoteId, Akonadi2::Storage::Transaction &transaction);
47 void removeRemoteId(const QByteArray &bufferType, const QByteArray &localId, const QByteArray &remoteId, Akonadi2::Storage::Transaction &transaction);
48
49 /**
44 * Tries to find a local id for the remote id, and creates a new local id otherwise. 50 * Tries to find a local id for the remote id, and creates a new local id otherwise.
45 * 51 *
46 * The new local id is recorded in the local to remote id mapping. 52 * The new local id is recorded in the local to remote id mapping.