From ae7cc26c8350b427870f83687f83184c2c211250 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Tue, 1 Dec 2015 15:48:54 +0100 Subject: Synchronizer: One transaction per sync, and check if entity already exists. With this we no longer repeatedly create entities on every sync. --- examples/dummyresource/resourcefactory.cpp | 59 +++++++++++++++--------------- examples/dummyresource/resourcefactory.h | 10 ++--- 2 files changed, 35 insertions(+), 34 deletions(-) (limited to 'examples') 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 } } -void DummyResource::createEvent(const QByteArray &ridBuffer, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb) +void DummyResource::createEvent(const QByteArray &ridBuffer, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &transaction) { //Map the source format to the buffer format (which happens to be an exact copy here) auto summary = m_fbb.CreateString(data.value("summary").toString().toStdString()); @@ -160,7 +160,7 @@ void DummyResource::createEvent(const QByteArray &ridBuffer, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb) +void DummyResource::createMail(const QByteArray &ridBuffer, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &transaction) { //Map the source format to the buffer format (which happens to be an exact copy here) auto subject = m_fbb.CreateString(data.value("subject").toString().toStdString()); @@ -182,11 +182,9 @@ void DummyResource::createMail(const QByteArray &ridBuffer, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb) +void DummyResource::createFolder(const QByteArray &ridBuffer, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &transaction) { //Map the source format to the buffer format (which happens to be an exact copy here) auto name = m_fbb.CreateString(data.value("name").toString().toStdString()); @@ -203,7 +201,7 @@ void DummyResource::createFolder(const QByteArray &ridBuffer, const QMap > &data, Akonadi2::Storage::Transaction &transaction, std::function &data, flatbuffers::FlatBufferBuilder &entityFbb)> createEntity) +void DummyResource::synchronize(const QString &bufferType, const QMap > &data, Akonadi2::Storage::Transaction &transaction, std::function &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &)> createEntity) { - Index uidIndex("index.uid", transaction); + Akonadi2::Storage store(Akonadi2::storageLocation(), mResourceInstanceIdentifier + ".synchronization", Akonadi2::Storage::ReadWrite); + auto synchronizationTransaction = store.createTransaction(Akonadi2::Storage::ReadWrite); + Index ridMapping("rid.mapping", synchronizationTransaction); for (auto it = data.constBegin(); it != data.constEnd(); it++) { - bool isNew = true; - uidIndex.lookup(it.key().toLatin1(), [&](const QByteArray &value) { - isNew = false; - }, - [](const Index::Error &error) { - if (error.code != Index::IndexNotAvailable) { - Warning() << "Error in uid index: " << error.message; - } - }); - if (isNew) { + const auto remoteId = it.key().toUtf8(); + auto akonadiId = resolveRemoteId(remoteId, synchronizationTransaction); + + bool found = false; + transaction.openDatabase(bufferType.toUtf8() + ".main").scan(akonadiId.toUtf8(), [&found](const QByteArray &, const QByteArray &) -> bool { + found = true; + return false; + }, [this](const Akonadi2::Storage::Error &error) { + }, true); + + if (!found) { //A new entity m_fbb.Clear(); flatbuffers::FlatBufferBuilder entityFbb; - createEntity(it.key().toUtf8(), it.value(), entityFbb); - - auto akonadiId = resolveRemoteId(it.key()); + createEntity(remoteId, it.value(), entityFbb, synchronizationTransaction); flatbuffers::FlatBufferBuilder fbb; //This is the resource type and not the domain type @@ -246,8 +245,10 @@ void DummyResource::synchronize(const QString &bufferType, const QMap(fbb.GetBufferPointer()), fbb.GetSize())); } else { //modification + Trace() << "Found a modified entity: " << remoteId; //TODO diff and create modification if necessary } } @@ -260,14 +261,14 @@ KAsync::Job DummyResource::synchronizeWithSource() return KAsync::start([this](KAsync::Future &f) { auto transaction = Akonadi2::Storage(Akonadi2::storageLocation(), mResourceInstanceIdentifier, Akonadi2::Storage::ReadOnly).createTransaction(Akonadi2::Storage::ReadOnly); - synchronize(ENTITY_TYPE_EVENT, DummyStore::instance().events(), transaction, [this](const QByteArray &ridBuffer, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb) { - createEvent(ridBuffer, data, entityFbb); + synchronize(ENTITY_TYPE_EVENT, DummyStore::instance().events(), transaction, [this](const QByteArray &ridBuffer, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &synchronizationTransaction) { + createEvent(ridBuffer, data, entityFbb, synchronizationTransaction); }); - synchronize(ENTITY_TYPE_MAIL, DummyStore::instance().mails(), transaction, [this](const QByteArray &ridBuffer, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb) { - createMail(ridBuffer, data, entityFbb); + synchronize(ENTITY_TYPE_MAIL, DummyStore::instance().mails(), transaction, [this](const QByteArray &ridBuffer, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &synchronizationTransaction) { + createMail(ridBuffer, data, entityFbb, synchronizationTransaction); }); - synchronize(ENTITY_TYPE_FOLDER, DummyStore::instance().folders(), transaction, [this](const QByteArray &ridBuffer, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb) { - createFolder(ridBuffer, data, entityFbb); + synchronize(ENTITY_TYPE_FOLDER, DummyStore::instance().folders(), transaction, [this](const QByteArray &ridBuffer, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &synchronizationTransaction) { + createFolder(ridBuffer, data, entityFbb, synchronizationTransaction); }); f.setFinished(); @@ -277,7 +278,7 @@ KAsync::Job DummyResource::synchronizeWithSource() void DummyResource::removeFromDisk(const QByteArray &instanceIdentifier) { GenericResource::removeFromDisk(instanceIdentifier); - Akonadi2::Storage(Akonadi2::storageLocation(), instanceIdentifier + ".event.index.uid", Akonadi2::Storage::ReadWrite).removeFromDisk(); + Akonadi2::Storage(Akonadi2::storageLocation(), instanceIdentifier + ".synchronization", Akonadi2::Storage::ReadWrite).removeFromDisk(); } DummyResourceFactory::DummyResourceFactory(QObject *parent) diff --git a/examples/dummyresource/resourcefactory.h b/examples/dummyresource/resourcefactory.h index f7882ca..5706c16 100644 --- a/examples/dummyresource/resourcefactory.h +++ b/examples/dummyresource/resourcefactory.h @@ -36,11 +36,11 @@ public: KAsync::Job synchronizeWithSource() Q_DECL_OVERRIDE; static void removeFromDisk(const QByteArray &instanceIdentifier); private: - QString resolveRemoteId(const QString &remoteId); - void createEvent(const QByteArray &rid, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb); - void createMail(const QByteArray &rid, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb); - void createFolder(const QByteArray &rid, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb); - void synchronize(const QString &bufferType, const QMap > &data, Akonadi2::Storage::Transaction &transaction, std::function &data, flatbuffers::FlatBufferBuilder &entityFbb)> createEntity); + QString resolveRemoteId(const QString &remoteId, Akonadi2::Storage::Transaction &transaction); + void createEvent(const QByteArray &rid, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &); + void createMail(const QByteArray &rid, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &); + void createFolder(const QByteArray &rid, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &); + void synchronize(const QString &bufferType, const QMap > &data, Akonadi2::Storage::Transaction &transaction, std::function &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &)> createEntity); }; class DummyResourceFactory : public Akonadi2::ResourceFactory -- cgit v1.2.3