From d4b10a3de396eebc6c815093e9e1725ece270e9e Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Sun, 15 Nov 2015 11:09:31 +0100 Subject: Working folder tree query --- common/domain/folder.cpp | 28 +++++++++ common/modelresult.h | 5 +- examples/dummyresource/resourcefactory.cpp | 6 ++ tests/querytest.cpp | 98 ++++++++++++++++++++---------- 4 files changed, 102 insertions(+), 35 deletions(-) diff --git a/common/domain/folder.cpp b/common/domain/folder.cpp index 50f73c2..82f6c1f 100644 --- a/common/domain/folder.cpp +++ b/common/domain/folder.cpp @@ -37,15 +37,43 @@ using namespace Akonadi2::ApplicationDomain; ResultSet TypeImplementation::queryIndexes(const Akonadi2::Query &query, const QByteArray &resourceInstanceIdentifier, QSet &appliedFilters, Akonadi2::Storage::Transaction &transaction) { QVector keys; + if (query.propertyFilter.contains("parent")) { + Index index("folder.index.parent", transaction); + auto lookupKey = query.propertyFilter.value("parent").toByteArray(); + if (lookupKey.isEmpty()) { + lookupKey = "toplevel"; + } + index.lookup(lookupKey, [&](const QByteArray &value) { + keys << value; + }, + [](const Index::Error &error) { + Warning() << "Error in uid index: " << error.message; + }); + appliedFilters << "parent"; + } + Trace() << "Index lookup found " << keys.size() << " keys."; return ResultSet(keys); } void TypeImplementation::index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Akonadi2::Storage::Transaction &transaction) { + const auto parent = bufferAdaptor.getProperty("parent"); + Trace() << "indexing " << identifier << " with parent " << parent.toByteArray(); + if (parent.isValid()) { + Index("folder.index.parent", transaction).add(parent.toByteArray(), identifier); + } else { + Index("folder.index.parent", transaction).add("toplevel", identifier); + } } void TypeImplementation::removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Akonadi2::Storage::Transaction &transaction) { + const auto parent = bufferAdaptor.getProperty("parent"); + if (parent.isValid()) { + Index("folder.index.parent", transaction).remove(parent.toByteArray(), identifier); + } else { + Index("folder.index.parent", transaction).remove("toplevel", identifier); + } } QSharedPointer::Buffer> > TypeImplementation::initializeReadPropertyMapper() diff --git a/common/modelresult.h b/common/modelresult.h index eabb868..8ca6daa 100644 --- a/common/modelresult.h +++ b/common/modelresult.h @@ -116,7 +116,7 @@ public: return; } auto parent = createIndexFromId(id); - qDebug() << "Added entity " << childId; + qDebug() << "Added entity " << childId << value->identifier(); const auto keys = mTree[id]; int index = 0; for (; index < keys.size(); index++) { @@ -166,7 +166,6 @@ public: void fetchEntities(const QModelIndex &parent) { - qDebug() << "Fetching entities"; const auto id = getIdentifier(parent); mEntityChildrenFetched[id] = true; QByteArray parentIdentifier; @@ -178,7 +177,7 @@ public: Q_ASSERT(object); parentIdentifier = object->identifier(); } - Trace() << "Loading entities"; + Trace() << "Loading child entities of: " << parentIdentifier; loadEntities(parentIdentifier); } diff --git a/examples/dummyresource/resourcefactory.cpp b/examples/dummyresource/resourcefactory.cpp index edb3b42..bed1d71 100644 --- a/examples/dummyresource/resourcefactory.cpp +++ b/examples/dummyresource/resourcefactory.cpp @@ -114,6 +114,12 @@ DummyResource::DummyResource(const QByteArray &instanceIdentifier, const QShared mPipeline->setPreprocessors(ENTITY_TYPE_MAIL, QVector() << mailIndexer); mPipeline->setAdaptorFactory(ENTITY_TYPE_MAIL, mailFactory); } + { + auto folderFactory = QSharedPointer::create(); + auto folderIndexer = new IndexUpdater("folder.index.rid", ENTITY_TYPE_FOLDER); + mPipeline->setPreprocessors(ENTITY_TYPE_FOLDER, QVector() << folderIndexer); + mPipeline->setAdaptorFactory(ENTITY_TYPE_FOLDER, folderFactory); + } } void DummyResource::createEvent(const QByteArray &ridBuffer, const QMap &data, flatbuffers::FlatBufferBuilder &entityFbb) diff --git a/tests/querytest.cpp b/tests/querytest.cpp index e4f1d0d..677dbac 100644 --- a/tests/querytest.cpp +++ b/tests/querytest.cpp @@ -90,38 +90,72 @@ private Q_SLOTS: QTRY_COMPARE(model->rowCount(), 1); } - // void testTree() - // { - // //Setup - // { - // Akonadi2::ApplicationDomain::Folder folder("org.kde.dummy.instance1"); - // Akonadi2::Store::create(folder).exec().waitForFinished(); - // - // Akonadi2::Query query; - // query.resources << "org.kde.dummy.instance1"; - // query.syncOnDemand = false; - // query.processAll = true; - // - // auto model = new ModelResult(query, QList() << "summary" << "uid"); - // QTRY_COMPARE(model->rowCount(), 1); - // - // auto folderEntity = model->index(0, 0).data(ModelResult::DomainObjectRole).value(); - // - // Akonadi2::ApplicationDomain::Folder subfolder("org.kde.dummy.instance1"); - // subfolder.setProperty("parent", folderEntity.identifier()); - // Akonadi2::Store::create(subfolder).exec().waitForFinished(); - // } - // - // //Test - // Akonadi2::Query query; - // query.resources << "org.kde.dummy.instance1"; - // query.syncOnDemand = false; - // query.processAll = true; - // - // auto model = new ModelResult(query, QList() << "summary" << "uid"); - // QTRY_COMPARE(model->rowCount(), 1); - // QTRY_COMPARE(model->rowCount(model->index(0, 0)), 1); - // } + void testFolder() + { + //Setup + { + Akonadi2::ApplicationDomain::Folder folder("org.kde.dummy.instance1"); + Akonadi2::Store::create(folder).exec().waitForFinished(); + } + + //Test + Akonadi2::Query query; + query.resources << "org.kde.dummy.instance1"; + query.syncOnDemand = false; + query.processAll = false; + query.liveQuery = true; + + //We fetch before the data is available and rely on the live query mechanism to deliver the actual data + auto model = Akonadi2::Store::loadModel(query); + model->fetchMore(QModelIndex()); + QTRY_COMPARE(model->rowCount(), 1); + auto folderEntity = model->index(0, 0).data(ModelResult::DomainObjectRole).value(); + QVERIFY(!folderEntity->identifier().isEmpty()); + } + + void testFolderTree() + { + //Setup + { + Akonadi2::ApplicationDomain::Folder folder("org.kde.dummy.instance1"); + Akonadi2::Store::create(folder).exec().waitForFinished(); + + Akonadi2::Query query; + query.resources << "org.kde.dummy.instance1"; + query.syncOnDemand = false; + query.processAll = true; + + //Ensure all local data is processed + Akonadi2::Store::synchronize(query).exec().waitForFinished(); + + auto model = Akonadi2::Store::loadModel(query); + model->fetchMore(QModelIndex()); + QTRY_COMPARE(model->rowCount(), 1); + + auto folderEntity = model->index(0, 0).data(ModelResult::DomainObjectRole).value(); + QVERIFY(!folderEntity->identifier().isEmpty()); + + Akonadi2::ApplicationDomain::Folder subfolder("org.kde.dummy.instance1"); + subfolder.setProperty("parent", folderEntity->identifier()); + Akonadi2::Store::create(subfolder).exec().waitForFinished(); + } + + //Test + Akonadi2::Query query; + query.resources << "org.kde.dummy.instance1"; + query.syncOnDemand = false; + query.processAll = true; + + //Ensure all local data is processed + Akonadi2::Store::synchronize(query).exec().waitForFinished(); + + //We fetch after the data is available and don't rely on the live query mechanism to deliver the actual data + auto model = Akonadi2::Store::loadModel(query); + model->fetchMore(QModelIndex()); + QTRY_COMPARE(model->rowCount(), 1); + model->fetchMore(model->index(0, 0)); + QTRY_COMPARE(model->rowCount(model->index(0, 0)), 1); + } }; QTEST_MAIN(QueryTest) -- cgit v1.2.3