From a638278ede2d7af9a073da6ca11ba2efee2a934b Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Wed, 7 Jan 2015 01:01:42 +0100 Subject: Made the domain adaptor actually work. We can read stuff now. --- common/clientapi.h | 21 +++++- common/entitybuffer.cpp | 18 ++--- common/entitybuffer.h | 8 +- dummyresource/domainadaptor.cpp | 11 ++- dummyresource/facade.cpp | 8 +- dummyresource/resourcefactory.cpp | 6 +- tests/CMakeLists.txt | 1 + tests/domainadaptortest.cpp | 154 ++++++++++++++++++++++++++++++++++++++ tests/dummyresourcetest.cpp | 2 +- 9 files changed, 207 insertions(+), 22 deletions(-) create mode 100644 tests/domainadaptortest.cpp diff --git a/common/clientapi.h b/common/clientapi.h index ba0cb19..d2b1c9c 100644 --- a/common/clientapi.h +++ b/common/clientapi.h @@ -178,8 +178,27 @@ namespace Domain { */ class BufferAdaptor { public: - virtual QVariant getProperty(const QString &key) { return QVariant(); } + virtual QVariant getProperty(const QString &key) const { return QVariant(); } virtual void setProperty(const QString &key, const QVariant &value) {} + virtual QStringList availableProperties() const { return QStringList(); } +}; + +class MemoryBufferAdaptor : public BufferAdaptor { +public: + MemoryBufferAdaptor(const BufferAdaptor &buffer) + : BufferAdaptor() + { + for(const auto &property : buffer.availableProperties()) { + mValues.insert(property, buffer.getProperty(property)); + } + } + + virtual QVariant getProperty(const QString &key) const { return mValues.value(key); } + virtual void setProperty(const QString &key, const QVariant &value) { mValues.insert(key, value); } + virtual QStringList availableProperties() const { return mValues.keys(); } + +private: + QHash mValues; }; /** diff --git a/common/entitybuffer.cpp b/common/entitybuffer.cpp index c5d6bce..aa5847c 100644 --- a/common/entitybuffer.cpp +++ b/common/entitybuffer.cpp @@ -23,36 +23,36 @@ const Akonadi2::Entity &EntityBuffer::entity() return *mEntity; } -const flatbuffers::Vector* EntityBuffer::resourceBuffer() +const uint8_t* EntityBuffer::resourceBuffer() { if (!mEntity) { qDebug() << "no buffer"; return nullptr; } - return mEntity->resource(); + return mEntity->resource()->Data(); } -const flatbuffers::Vector* EntityBuffer::metadataBuffer() +const uint8_t* EntityBuffer::metadataBuffer() { if (!mEntity) { return nullptr; } - return mEntity->metadata(); + return mEntity->metadata()->Data(); } -const flatbuffers::Vector* EntityBuffer::localBuffer() +const uint8_t* EntityBuffer::localBuffer() { if (!mEntity) { return nullptr; } - return mEntity->local(); + return mEntity->local()->Data(); } -void EntityBuffer::extractResourceBuffer(void *dataValue, int dataSize, const std::function *)> &handler) +void EntityBuffer::extractResourceBuffer(void *dataValue, int dataSize, const std::function &handler) { Akonadi2::EntityBuffer buffer(dataValue, dataSize); - if (auto resourceData = buffer.resourceBuffer()) { - handler(resourceData); + if (auto resourceData = buffer.entity().resource()) { + handler(resourceData->Data(), resourceData->size()); } } diff --git a/common/entitybuffer.h b/common/entitybuffer.h index bd9360d..600b04d 100644 --- a/common/entitybuffer.h +++ b/common/entitybuffer.h @@ -9,12 +9,12 @@ class Entity; class EntityBuffer { public: EntityBuffer(void *dataValue, int size); - const flatbuffers::Vector *resourceBuffer(); - const flatbuffers::Vector *metadataBuffer(); - const flatbuffers::Vector *localBuffer(); + const uint8_t *resourceBuffer(); + const uint8_t *metadataBuffer(); + const uint8_t *localBuffer(); const Entity &entity(); - static void extractResourceBuffer(void *dataValue, int dataSize, const std::function *)> &handler); + static void extractResourceBuffer(void *dataValue, int dataSize, const std::function &handler); static void assembleEntityBuffer(flatbuffers::FlatBufferBuilder &fbb, void *metadataData, size_t metadataSize, void *resourceData, size_t resourceSize, void *localData, size_t localSize); private: diff --git a/dummyresource/domainadaptor.cpp b/dummyresource/domainadaptor.cpp index 5d046ff..ae001cf 100644 --- a/dummyresource/domainadaptor.cpp +++ b/dummyresource/domainadaptor.cpp @@ -46,6 +46,14 @@ public: return QVariant(); } + virtual QStringList availableProperties() const + { + QStringList props; + props << mResourceMapper->mReadAccessors.keys(); + props << mLocalMapper->mReadAccessors.keys(); + return props; + } + Akonadi2::Domain::Buffer::Event const *mLocalBuffer; DummyEvent const *mResourceBuffer; @@ -65,13 +73,14 @@ DummyEventAdaptorFactory::DummyEventAdaptorFactory() } +//TODO pass EntityBuffer instead? QSharedPointer DummyEventAdaptorFactory::createAdaptor(const Akonadi2::Entity &entity) { DummyEvent const *resourceBuffer = 0; if (auto resourceData = entity.resource()) { flatbuffers::Verifier verifyer(resourceData->Data(), resourceData->size()); if (VerifyDummyEventBuffer(verifyer)) { - resourceBuffer = GetDummyEvent(resourceData); + resourceBuffer = GetDummyEvent(resourceData->Data()); } } diff --git a/dummyresource/facade.cpp b/dummyresource/facade.cpp index 5320216..f754c7e 100644 --- a/dummyresource/facade.cpp +++ b/dummyresource/facade.cpp @@ -128,7 +128,7 @@ void DummyResourceFacade::load(const Akonadi2::Query &query, const std::function Akonadi2::EntityBuffer buffer(dataValue, dataSize); DummyEvent const *resourceBuffer = 0; - if (auto resourceData = buffer.resourceBuffer()) { + if (auto resourceData = buffer.entity().resource()) { flatbuffers::Verifier verifyer(resourceData->Data(), resourceData->size()); if (VerifyDummyEventBuffer(verifyer)) { resourceBuffer = GetDummyEvent(resourceData); @@ -136,7 +136,7 @@ void DummyResourceFacade::load(const Akonadi2::Query &query, const std::function } Akonadi2::Metadata const *metadataBuffer = 0; - if (auto metadataData = buffer.metadataBuffer()) { + if (auto metadataData = buffer.entity().metadata()) { flatbuffers::Verifier verifyer(metadataData->Data(), metadataData->size()); if (Akonadi2::VerifyMetadataBuffer(verifyer)) { metadataBuffer = Akonadi2::GetMetadata(metadataData); @@ -153,7 +153,9 @@ void DummyResourceFacade::load(const Akonadi2::Query &query, const std::function if (preparedQuery && preparedQuery(std::string(static_cast(keyValue), keySize), resourceBuffer)) { qint64 revision = metadataBuffer ? metadataBuffer->revision() : -1; auto adaptor = mFactory->createAdaptor(buffer.entity()); - auto event = QSharedPointer::create("org.kde.dummy", QString::fromUtf8(static_cast(keyValue), keySize), revision, adaptor); + //TODO only copy requested properties + auto memoryAdaptor = QSharedPointer::create(*adaptor); + auto event = QSharedPointer::create("org.kde.dummy", QString::fromUtf8(static_cast(keyValue), keySize), revision, memoryAdaptor); resultCallback(event); } return true; diff --git a/dummyresource/resourcefactory.cpp b/dummyresource/resourcefactory.cpp index 87a6048..e4f7e41 100644 --- a/dummyresource/resourcefactory.cpp +++ b/dummyresource/resourcefactory.cpp @@ -122,10 +122,10 @@ void findByRemoteId(QSharedPointer storage, const QString &ri return true; } - Akonadi2::EntityBuffer::extractResourceBuffer(dataValue, dataSize, [&](const flatbuffers::Vector *buffer) { - flatbuffers::Verifier verifier(buffer->Data(), buffer->size()); + Akonadi2::EntityBuffer::extractResourceBuffer(dataValue, dataSize, [&](const uint8_t *buffer, size_t size) { + flatbuffers::Verifier verifier(buffer, size); if (DummyCalendar::VerifyDummyEventBuffer(verifier)) { - DummyCalendar::DummyEvent const *resourceBuffer = DummyCalendar::GetDummyEvent(buffer->Data()); + DummyCalendar::DummyEvent const *resourceBuffer = DummyCalendar::GetDummyEvent(buffer); if (resourceBuffer && resourceBuffer->remoteId()) { if (std::string(resourceBuffer->remoteId()->c_str(), resourceBuffer->remoteId()->size()) == ridString) { callback(keyValue, keySize, dataValue, dataSize); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8a1069d..12695ff 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -17,6 +17,7 @@ manual_tests ( storagebenchmark storagetest dummyresourcetest + domainadaptortest ) target_link_libraries(dummyresourcetest akonadi2_resource_dummy) diff --git a/tests/domainadaptortest.cpp b/tests/domainadaptortest.cpp new file mode 100644 index 0000000..d1a9d26 --- /dev/null +++ b/tests/domainadaptortest.cpp @@ -0,0 +1,154 @@ +#include + +#include +#include +#include + +#include "dummyresource/resourcefactory.h" +#include "clientapi.h" + +#include "common/domainadaptor.h" +#include "common/entitybuffer.h" +#include "event_generated.h" +#include "metadata_generated.h" +#include "entity_generated.h" + +class TestEventAdaptor : public Akonadi2::Domain::BufferAdaptor +{ +public: + TestEventAdaptor() + : Akonadi2::Domain::BufferAdaptor() + { + } + + void setProperty(const QString &key, const QVariant &value) + { + if (mResourceMapper->mWriteAccessors.contains(key)) { + // mResourceMapper.setProperty(key, value, mResourceBuffer); + } else { + // mLocalMapper.; + } + } + + virtual QVariant getProperty(const QString &key) const + { + if (mResourceBuffer && mResourceMapper->mReadAccessors.contains(key)) { + return mResourceMapper->getProperty(key, mResourceBuffer); + } else if (mLocalBuffer) { + return mLocalMapper->getProperty(key, mLocalBuffer); + } + return QVariant(); + } + + Akonadi2::Domain::Buffer::Event const *mLocalBuffer; + Akonadi2::Domain::Buffer::Event const *mResourceBuffer; + + QSharedPointer > mLocalMapper; + QSharedPointer > mResourceMapper; +}; + +class TestFactory : public DomainTypeAdaptorFactory +{ +public: + TestFactory() + { + mResourceMapper = QSharedPointer >::create(); + mResourceMapper->mReadAccessors.insert("summary", [](Akonadi2::Domain::Buffer::Event const *buffer) -> QVariant { + if (buffer->summary()) { + return QString::fromStdString(buffer->summary()->c_str()); + } + return QVariant(); + }); + } + + virtual QSharedPointer createAdaptor(const Akonadi2::Entity &entity) + { + Akonadi2::Domain::Buffer::Event const *resourceBuffer = 0; + if (auto resourceData = entity.resource()) { + flatbuffers::Verifier verifyer(resourceData->Data(), resourceData->size()); + if (Akonadi2::Domain::Buffer::VerifyEventBuffer(verifyer)) { + resourceBuffer = Akonadi2::Domain::Buffer::GetEvent(resourceData->Data()); + if (resourceBuffer->summary()) { + qDebug() << QString::fromStdString(std::string(resourceBuffer->summary()->c_str())); + } + } + } + + Akonadi2::Metadata const *metadataBuffer = 0; + if (auto metadataData = entity.metadata()) { + flatbuffers::Verifier verifyer(metadataData->Data(), metadataData->size()); + if (Akonadi2::VerifyMetadataBuffer(verifyer)) { + metadataBuffer = Akonadi2::GetMetadata(metadataData); + } + } + + Akonadi2::Domain::Buffer::Event const *localBuffer = 0; + if (auto localData = entity.local()) { + flatbuffers::Verifier verifyer(localData->Data(), localData->size()); + if (Akonadi2::Domain::Buffer::VerifyEventBuffer(verifyer)) { + localBuffer = Akonadi2::Domain::Buffer::GetEvent(localData); + } + } + + auto adaptor = QSharedPointer::create(); + adaptor->mLocalBuffer = localBuffer; + adaptor->mResourceBuffer = resourceBuffer; + adaptor->mResourceMapper = mResourceMapper; + adaptor->mLocalMapper = mLocalMapper; + return adaptor; + } +}; + +class DomainAdaptorTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase() + { + } + + void cleanupTestCase() + { + } + + void testAdaptor() + { + //Create entity buffer + flatbuffers::FlatBufferBuilder metadataFbb; + auto metadataBuilder = Akonadi2::MetadataBuilder(metadataFbb); + metadataBuilder.add_revision(1); + metadataBuilder.add_processed(false); + auto metadataBuffer = metadataBuilder.Finish(); + Akonadi2::FinishMetadataBuffer(metadataFbb, metadataBuffer); + + flatbuffers::FlatBufferBuilder m_fbb; + auto summary = m_fbb.CreateString("summary1"); + auto description = m_fbb.CreateString("description"); + static uint8_t rawData[100]; + auto attachment = m_fbb.CreateVector(rawData, 100); + + auto builder = Akonadi2::Domain::Buffer::EventBuilder(m_fbb); + builder.add_summary(summary); + builder.add_description(description); + builder.add_attachment(attachment); + auto buffer = builder.Finish(); + Akonadi2::Domain::Buffer::FinishEventBuffer(m_fbb, buffer); + + flatbuffers::FlatBufferBuilder fbb; + Akonadi2::EntityBuffer::assembleEntityBuffer(fbb, metadataFbb.GetBufferPointer(), metadataFbb.GetSize(), m_fbb.GetBufferPointer(), m_fbb.GetSize(), m_fbb.GetBufferPointer(), m_fbb.GetSize()); + + //Extract entity buffer + { + std::string data(reinterpret_cast(fbb.GetBufferPointer()), fbb.GetSize()); + Akonadi2::EntityBuffer buffer((void*)(data.data()), data.size()); + + TestFactory factory; + auto adaptor = factory.createAdaptor(buffer.entity()); + QCOMPARE(adaptor->getProperty("summary").toString(), QString("summary1")); + } + } + +}; + +QTEST_MAIN(DomainAdaptorTest) +#include "domainadaptortest.moc" diff --git a/tests/dummyresourcetest.cpp b/tests/dummyresourcetest.cpp index 8e60e90..b39b2b1 100644 --- a/tests/dummyresourcetest.cpp +++ b/tests/dummyresourcetest.cpp @@ -39,7 +39,7 @@ private Q_SLOTS: result.exec(); QVERIFY(!result.isEmpty()); auto value = result.first(); - qDebug() << value->getProperty("summary"); + QVERIFY(!value->getProperty("summary").toString().isEmpty()); } }; -- cgit v1.2.3