From bbbda3fe9444eba6795a5490da0425cdf8f26361 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Tue, 8 Sep 2015 21:08:54 +0200 Subject: Added support for mails to akonadi and the dummyresource. Adding new types definitely needs to become easier. --- examples/dummyresource/domainadaptor.cpp | 6 ++ examples/dummyresource/domainadaptor.h | 9 +++ examples/dummyresource/dummystore.cpp | 33 +++++++- examples/dummyresource/dummystore.h | 4 +- examples/dummyresource/facade.cpp | 8 ++ examples/dummyresource/facade.h | 7 ++ examples/dummyresource/resourcefactory.cpp | 126 ++++++++++++++++++++++++----- examples/dummyresource/resourcefactory.h | 3 + 8 files changed, 171 insertions(+), 25 deletions(-) (limited to 'examples/dummyresource') diff --git a/examples/dummyresource/domainadaptor.cpp b/examples/dummyresource/domainadaptor.cpp index 4cc592e..d08a783 100644 --- a/examples/dummyresource/domainadaptor.cpp +++ b/examples/dummyresource/domainadaptor.cpp @@ -45,3 +45,9 @@ DummyEventAdaptorFactory::DummyEventAdaptorFactory() }); } +DummyMailAdaptorFactory::DummyMailAdaptorFactory() + : DomainTypeAdaptorFactory() +{ + +} + diff --git a/examples/dummyresource/domainadaptor.h b/examples/dummyresource/domainadaptor.h index 8b6d96b..add3e8e 100644 --- a/examples/dummyresource/domainadaptor.h +++ b/examples/dummyresource/domainadaptor.h @@ -20,6 +20,7 @@ #include "common/domainadaptor.h" #include "event_generated.h" +#include "mail_generated.h" #include "dummycalendar_generated.h" #include "entity_generated.h" @@ -29,3 +30,11 @@ public: DummyEventAdaptorFactory(); virtual ~DummyEventAdaptorFactory() {}; }; + +//TODO replace the resource specific event class by a mail class or a dummy class if no resource type is required. +class DummyMailAdaptorFactory : public DomainTypeAdaptorFactory +{ +public: + DummyMailAdaptorFactory(); + virtual ~DummyMailAdaptorFactory() {}; +}; diff --git a/examples/dummyresource/dummystore.cpp b/examples/dummyresource/dummystore.cpp index 5a3f74b..41b48ed 100644 --- a/examples/dummyresource/dummystore.cpp +++ b/examples/dummyresource/dummystore.cpp @@ -21,6 +21,7 @@ #include #include "dummycalendar_generated.h" +#include "mail_generated.h" static std::string createEvent(int i) { @@ -43,6 +44,20 @@ static std::string createEvent(int i) return std::string(reinterpret_cast(fbb.GetBufferPointer()), fbb.GetSize()); } +static std::string createMail(int i) +{ + static flatbuffers::FlatBufferBuilder fbb; + fbb.Clear(); + { + auto subject = fbb.CreateString("summary" + std::to_string(i)); + Akonadi2::ApplicationDomain::Buffer::MailBuilder mailBuilder(fbb); + mailBuilder.add_subject(subject); + Akonadi2::ApplicationDomain::Buffer::FinishMailBuffer(fbb, mailBuilder.Finish()); + } + + return std::string(reinterpret_cast(fbb.GetBufferPointer()), fbb.GetSize()); +} + QMap populate() { QMap content; @@ -53,10 +68,24 @@ QMap populate() return content; } -static QMap s_dataSource = populate(); +QMap populateMails() +{ + QMap content; + for (int i = 0; i < 2; i++) { + content.insert(QString("key%1").arg(i), QString::fromStdString(createMail(i))); + } + return content; +} +static QMap s_dataSource = populate(); +static QMap s_mailSource = populateMails(); -QMap DummyStore::data() const +QMap DummyStore::events() const { return s_dataSource; } + +QMap DummyStore::mails() const +{ + return s_mailSource; +} diff --git a/examples/dummyresource/dummystore.h b/examples/dummyresource/dummystore.h index 6a404ae..ba1c0ae 100644 --- a/examples/dummyresource/dummystore.h +++ b/examples/dummyresource/dummystore.h @@ -29,6 +29,6 @@ public: return instance; } - QMap data() const; - + QMap events() const; + QMap mails() const; }; diff --git a/examples/dummyresource/facade.cpp b/examples/dummyresource/facade.cpp index d20d12d..63f84f2 100644 --- a/examples/dummyresource/facade.cpp +++ b/examples/dummyresource/facade.cpp @@ -30,3 +30,11 @@ DummyResourceFacade::~DummyResourceFacade() { } +DummyResourceMailFacade::DummyResourceMailFacade(const QByteArray &instanceIdentifier) + : Akonadi2::GenericFacade(instanceIdentifier, QSharedPointer::create()) +{ +} + +DummyResourceMailFacade::~DummyResourceMailFacade() +{ +} diff --git a/examples/dummyresource/facade.h b/examples/dummyresource/facade.h index dde0dc2..87f68c3 100644 --- a/examples/dummyresource/facade.h +++ b/examples/dummyresource/facade.h @@ -28,3 +28,10 @@ public: DummyResourceFacade(const QByteArray &instanceIdentifier); virtual ~DummyResourceFacade(); }; + +class DummyResourceMailFacade : public Akonadi2::GenericFacade +{ +public: + DummyResourceMailFacade(const QByteArray &instanceIdentifier); + virtual ~DummyResourceMailFacade(); +}; diff --git a/examples/dummyresource/resourcefactory.cpp b/examples/dummyresource/resourcefactory.cpp index 0e18282..8d605b9 100644 --- a/examples/dummyresource/resourcefactory.cpp +++ b/examples/dummyresource/resourcefactory.cpp @@ -23,6 +23,7 @@ #include "entitybuffer.h" #include "pipeline.h" #include "dummycalendar_generated.h" +#include "mail_generated.h" #include "queuedcommand_generated.h" #include "createentity_generated.h" #include "domainadaptor.h" @@ -30,21 +31,23 @@ #include "index.h" #include "log.h" #include "domain/event.h" +#include "domain/mail.h" #include "dummystore.h" #include "definitions.h" #include "facadefactory.h" //This is the resources entity type, and not the domain type #define ENTITY_TYPE_EVENT "event" +#define ENTITY_TYPE_MAIL "mail" DummyResource::DummyResource(const QByteArray &instanceIdentifier, const QSharedPointer &pipeline) : Akonadi2::GenericResource(instanceIdentifier, pipeline) { auto eventFactory = QSharedPointer::create(); const auto resourceIdentifier = mResourceInstanceIdentifier; + auto eventIndexer = new Akonadi2::SimpleProcessor("eventIndexer", [eventFactory, resourceIdentifier](const Akonadi2::PipelineState &state, const Akonadi2::Entity &entity, Akonadi2::Storage::Transaction &transaction) { auto adaptor = eventFactory->createAdaptor(entity); - //FIXME set revision? Akonadi2::ApplicationDomain::Event event(resourceIdentifier, state.key(), -1, adaptor); Akonadi2::ApplicationDomain::TypeImplementation::index(event, transaction); @@ -58,15 +61,75 @@ DummyResource::DummyResource(const QByteArray &instanceIdentifier, const QShared mPipeline->setPreprocessors(ENTITY_TYPE_EVENT, Akonadi2::Pipeline::NewPipeline, QVector() << eventIndexer); mPipeline->setAdaptorFactory(ENTITY_TYPE_EVENT, eventFactory); //TODO cleanup indexes during removal + + { + auto mailFactory = QSharedPointer::create(); + auto mailIndexer = new Akonadi2::SimpleProcessor("mailIndexer", [mailFactory, resourceIdentifier](const Akonadi2::PipelineState &state, const Akonadi2::Entity &entity, Akonadi2::Storage::Transaction &transaction) { + auto adaptor = mailFactory->createAdaptor(entity); + Akonadi2::ApplicationDomain::Mail mail(resourceIdentifier, state.key(), -1, adaptor); + Akonadi2::ApplicationDomain::TypeImplementation::index(mail, transaction); + + Index ridIndex("mail.index.rid", transaction); + const auto rid = mail.getProperty("remoteId"); + if (rid.isValid()) { + ridIndex.add(rid.toByteArray(), mail.identifier()); + } + }); + + mPipeline->setPreprocessors(ENTITY_TYPE_MAIL, Akonadi2::Pipeline::NewPipeline, QVector() << mailIndexer); + mPipeline->setAdaptorFactory(ENTITY_TYPE_MAIL, mailFactory); + } +} + +void DummyResource::createEvent(const QByteArray &ridBuffer, const QByteArray &data, flatbuffers::FlatBufferBuilder &entityFbb) +{ + auto eventBuffer = DummyCalendar::GetDummyEvent(data.data()); + + //Map the source format to the buffer format (which happens to be an exact copy here) + auto summary = m_fbb.CreateString(eventBuffer->summary()->c_str()); + auto rid = m_fbb.CreateString(std::string(ridBuffer.constData(), ridBuffer.size())); + auto description = m_fbb.CreateString(std::string(ridBuffer.constData(), ridBuffer.size())); + static uint8_t rawData[100]; + auto attachment = Akonadi2::EntityBuffer::appendAsVector(m_fbb, rawData, 100); + + auto builder = DummyCalendar::DummyEventBuilder(m_fbb); + builder.add_summary(summary); + builder.add_remoteId(rid); + builder.add_description(description); + builder.add_attachment(attachment); + auto buffer = builder.Finish(); + DummyCalendar::FinishDummyEventBuffer(m_fbb, buffer); + Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize(), 0, 0); +} + +void DummyResource::createMail(const QByteArray &ridBuffer, const QByteArray &data, flatbuffers::FlatBufferBuilder &entityFbb) +{ + auto mailBuffer = Akonadi2::ApplicationDomain::Buffer::GetMail(data.data()); + + //Map the source format to the buffer format (which happens to be an exact copy here) + auto subject = m_fbb.CreateString(mailBuffer->subject()->c_str()); + auto rid = m_fbb.CreateString(std::string(ridBuffer.constData(), ridBuffer.size())); + // auto description = m_fbb.CreateString(std::string(ridBuffer.constData(), ridBuffer.size())); + // static uint8_t rawData[100]; + // auto attachment = Akonadi2::EntityBuffer::appendAsVector(m_fbb, rawData, 100); + + auto builder = Akonadi2::ApplicationDomain::Buffer::MailBuilder(m_fbb); + builder.add_subject(subject); + // builder.add(rid); + // builder.add_description(description); + // builder.add_attachment(attachment); + auto buffer = builder.Finish(); + Akonadi2::ApplicationDomain::Buffer::FinishMailBuffer(m_fbb, buffer); + Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize()); } KAsync::Job DummyResource::synchronizeWithSource() { return KAsync::start([this](KAsync::Future &f) { - auto transaction = Akonadi2::Storage(Akonadi2::storageLocation(), mResourceInstanceIdentifier + ".index.uid", Akonadi2::Storage::ReadOnly).createTransaction(Akonadi2::Storage::ReadOnly); + auto transaction = Akonadi2::Storage(Akonadi2::storageLocation(), mResourceInstanceIdentifier, Akonadi2::Storage::ReadOnly).createTransaction(Akonadi2::Storage::ReadOnly); Index uidIndex("index.uid", transaction); - const auto data = DummyStore::instance().data(); + const auto data = DummyStore::instance().events(); for (auto it = data.constBegin(); it != data.constEnd(); it++) { bool isNew = true; uidIndex.lookup(it.key().toLatin1(), [&](const QByteArray &value) { @@ -80,25 +143,8 @@ KAsync::Job DummyResource::synchronizeWithSource() if (isNew) { m_fbb.Clear(); - const QByteArray data = it.value().toUtf8(); - auto eventBuffer = DummyCalendar::GetDummyEvent(data.data()); - - //Map the source format to the buffer format (which happens to be an exact copy here) - auto summary = m_fbb.CreateString(eventBuffer->summary()->c_str()); - auto rid = m_fbb.CreateString(it.key().toStdString().c_str()); - auto description = m_fbb.CreateString(it.key().toStdString().c_str()); - static uint8_t rawData[100]; - auto attachment = Akonadi2::EntityBuffer::appendAsVector(m_fbb, rawData, 100); - - auto builder = DummyCalendar::DummyEventBuilder(m_fbb); - builder.add_summary(summary); - builder.add_remoteId(rid); - builder.add_description(description); - builder.add_attachment(attachment); - auto buffer = builder.Finish(); - DummyCalendar::FinishDummyEventBuffer(m_fbb, buffer); flatbuffers::FlatBufferBuilder entityFbb; - Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize(), 0, 0); + createEvent(it.key().toUtf8(), it.value().toUtf8(), entityFbb); flatbuffers::FlatBufferBuilder fbb; //This is the resource type and not the domain type @@ -113,6 +159,43 @@ KAsync::Job DummyResource::synchronizeWithSource() } } //TODO find items to remove + + const auto mails = DummyStore::instance().mails(); + for (auto it = mails.constBegin(); it != mails.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) { + m_fbb.Clear(); + + flatbuffers::FlatBufferBuilder entityFbb; + createMail(it.key().toUtf8(), it.value().toUtf8(), entityFbb); + + flatbuffers::Verifier verifyer(reinterpret_cast(entityFbb.GetBufferPointer()), entityFbb.GetSize()); + if (!Akonadi2::ApplicationDomain::Buffer::VerifyMailBuffer(verifyer)) { + Warning() << "invalid buffer, not a mail buffer"; + } + + flatbuffers::FlatBufferBuilder fbb; + //This is the resource type and not the domain type + auto type = fbb.CreateString(ENTITY_TYPE_MAIL); + auto delta = Akonadi2::EntityBuffer::appendAsVector(fbb, entityFbb.GetBufferPointer(), entityFbb.GetSize()); + auto location = Akonadi2::Commands::CreateCreateEntity(fbb, type, delta); + Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location); + + enqueueCommand(mSynchronizerQueue, Akonadi2::Commands::CreateEntityCommand, QByteArray::fromRawData(reinterpret_cast(fbb.GetBufferPointer()), fbb.GetSize())); + } else { //modification + //TODO diff and create modification if necessary + } + } + //TODO find items to remove + f.setFinished(); }); } @@ -132,6 +215,7 @@ Akonadi2::Resource *DummyResourceFactory::createResource(const QByteArray &insta void DummyResourceFactory::registerFacades(Akonadi2::FacadeFactory &factory) { factory.registerFacade(PLUGIN_NAME); + factory.registerFacade(PLUGIN_NAME); } #include "resourcefactory.moc" diff --git a/examples/dummyresource/resourcefactory.h b/examples/dummyresource/resourcefactory.h index 4baafa7..cf0f624 100644 --- a/examples/dummyresource/resourcefactory.h +++ b/examples/dummyresource/resourcefactory.h @@ -34,6 +34,9 @@ class DummyResource : public Akonadi2::GenericResource public: DummyResource(const QByteArray &instanceIdentifier, const QSharedPointer &pipeline = QSharedPointer()); KAsync::Job synchronizeWithSource() Q_DECL_OVERRIDE; +private: + void createEvent(const QByteArray &rid, const QByteArray &data, flatbuffers::FlatBufferBuilder &entityFbb); + void createMail(const QByteArray &rid, const QByteArray &data, flatbuffers::FlatBufferBuilder &entityFbb); }; class DummyResourceFactory : public Akonadi2::ResourceFactory -- cgit v1.2.3