From 303a3cf5ba48dd9857a1fb9600cedd604c71de8d Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Sun, 6 Dec 2015 19:01:03 +0100 Subject: Added TypeIndex A central location for all types to specify what properties are indexed, and how to query them. --- common/CMakeLists.txt | 1 + common/domain/mail.cpp | 39 +++++++++--------- common/typeindex.cpp | 105 +++++++++++++++++++++++++++++++++++++++++++++++++ common/typeindex.h | 45 +++++++++++++++++++++ 4 files changed, 170 insertions(+), 20 deletions(-) create mode 100644 common/typeindex.cpp create mode 100644 common/typeindex.h (limited to 'common') diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index e56ece9..8312f13 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -32,6 +32,7 @@ set(command_SRCS threadboundary.cpp messagequeue.cpp index.cpp + typeindex.cpp resourcefacade.cpp resourceconfig.cpp domain/applicationdomaintype.cpp diff --git a/common/domain/mail.cpp b/common/domain/mail.cpp index 0170357..1a877cb 100644 --- a/common/domain/mail.cpp +++ b/common/domain/mail.cpp @@ -29,41 +29,40 @@ #include "../propertymapper.h" #include "../query.h" #include "../definitions.h" +#include "../typeindex.h" #include "mail_generated.h" using namespace Akonadi2::ApplicationDomain; -ResultSet TypeImplementation::queryIndexes(const Akonadi2::Query &query, const QByteArray &resourceInstanceIdentifier, QSet &appliedFilters, Akonadi2::Storage::Transaction &transaction) +static TypeIndex &getIndex() { - QVector keys; - if (query.propertyFilter.contains("uid")) { - Index uidIndex("mail.index.uid", transaction); - uidIndex.lookup(query.propertyFilter.value("uid").toByteArray(), [&](const QByteArray &value) { - keys << value; - }, - [](const Index::Error &error) { - Warning() << "Error in uid index: " << error.message; - }); - appliedFilters << "uid"; + static TypeIndex *index = 0; + if (!index) { + index = new TypeIndex("mail"); + index->addProperty("uid"); + index->addProperty("sender"); + index->addProperty("senderName"); + index->addProperty("subject"); + index->addProperty("date"); } - return ResultSet(keys); + return *index; +} + +ResultSet TypeImplementation::queryIndexes(const Akonadi2::Query &query, const QByteArray &resourceInstanceIdentifier, QSet &appliedFilters, Akonadi2::Storage::Transaction &transaction) +{ + return getIndex().query(query, appliedFilters, transaction); } void TypeImplementation::index(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Akonadi2::Storage::Transaction &transaction) { - const auto uid = bufferAdaptor.getProperty("uid"); - if (uid.isValid()) { - Index("mail.index.uid", transaction).add(uid.toByteArray(), identifier); - } + Trace() << "Indexing " << identifier; + getIndex().add(identifier, bufferAdaptor, transaction); } void TypeImplementation::removeIndex(const QByteArray &identifier, const BufferAdaptor &bufferAdaptor, Akonadi2::Storage::Transaction &transaction) { - const auto uid = bufferAdaptor.getProperty("uid"); - if (uid.isValid()) { - Index("mail.index.uid", transaction).remove(uid.toByteArray(), identifier); - } + getIndex().remove(identifier, bufferAdaptor, transaction); } QSharedPointer::Buffer> > TypeImplementation::initializeReadPropertyMapper() diff --git a/common/typeindex.cpp b/common/typeindex.cpp new file mode 100644 index 0000000..0a0dc33 --- /dev/null +++ b/common/typeindex.cpp @@ -0,0 +1,105 @@ +/* + Copyright (c) 2015 Christian Mollekopf + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ +#include "typeindex.h" + +#include "log.h" +#include "index.h" + +TypeIndex::TypeIndex(const QByteArray &type) + : mType(type) +{ + +} + +template<> +void TypeIndex::addProperty(const QByteArray &property) +{ + auto indexer = [this, property](const QByteArray &identifier, const QVariant &value, Akonadi2::Storage::Transaction &transaction) { + // Trace() << "Indexing " << mType + ".index." + property << value.toByteArray(); + Index(mType + ".index." + property, transaction).add(value.toByteArray(), identifier); + }; + mIndexer.insert(property, indexer); + mProperties << property; +} + +template<> +void TypeIndex::addProperty(const QByteArray &property) +{ + auto indexer = [this, property](const QByteArray &identifier, const QVariant &value, Akonadi2::Storage::Transaction &transaction) { + // Trace() << "Indexing " << mType + ".index." + property << value.toByteArray(); + Index(mType + ".index." + property, transaction).add(value.toByteArray(), identifier); + }; + mIndexer.insert(property, indexer); + mProperties << property; +} + +template<> +void TypeIndex::addProperty(const QByteArray &property) +{ + auto indexer = [this, property](const QByteArray &identifier, const QVariant &value, Akonadi2::Storage::Transaction &transaction) { + // Trace() << "Indexing " << mType + ".index." + property << value.toByteArray(); + Index(mType + ".index." + property, transaction).add(value.toByteArray(), identifier); + }; + mIndexer.insert(property, indexer); + mProperties << property; +} + +void TypeIndex::add(const QByteArray &identifier, const Akonadi2::ApplicationDomain::BufferAdaptor &bufferAdaptor, Akonadi2::Storage::Transaction &transaction) +{ + for (const auto &property : mProperties) { + const auto value = bufferAdaptor.getProperty(property); + if (value.isValid()) { + auto indexer = mIndexer.value(property); + indexer(identifier, value, transaction); + } + } +} + +void TypeIndex::remove(const QByteArray &identifier, const Akonadi2::ApplicationDomain::BufferAdaptor &bufferAdaptor, Akonadi2::Storage::Transaction &transaction) +{ + for (const auto &property : mProperties) { + const auto value = bufferAdaptor.getProperty(property); + if (value.isValid()) { + //FIXME don't always convert to byte array + Index(mType + ".index." + property, transaction).remove(value.toByteArray(), identifier); + } + } +} + +ResultSet TypeIndex::query(const Akonadi2::Query &query, QSet &appliedFilters, Akonadi2::Storage::Transaction &transaction) +{ + QVector keys; + for (const auto &property : mProperties) { + if (query.propertyFilter.contains(property)) { + Index index(mType + ".index." + property, transaction); + index.lookup(query.propertyFilter.value(property).toByteArray(), [&](const QByteArray &value) { + keys << value; + }, + [property](const Index::Error &error) { + Warning() << "Error in index: " << error.message << property; + }); + appliedFilters << property; + } + Trace() << "Index lookup found keys: " << keys.size(); + return ResultSet(keys); + } + Trace() << "No matching index"; + return ResultSet(keys); +} + diff --git a/common/typeindex.h b/common/typeindex.h new file mode 100644 index 0000000..fb66c2c --- /dev/null +++ b/common/typeindex.h @@ -0,0 +1,45 @@ +/* + Copyright (c) 2015 Christian Mollekopf + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ +#pragma once + +#include "resultset.h" +#include "bufferadaptor.h" +#include "storage.h" +#include "query.h" +#include + +class TypeIndex +{ +public: + TypeIndex(const QByteArray &type); + + template + void addProperty(const QByteArray &property); + + void add(const QByteArray &identifier, const Akonadi2::ApplicationDomain::BufferAdaptor &bufferAdaptor, Akonadi2::Storage::Transaction &transaction); + void remove(const QByteArray &identifier, const Akonadi2::ApplicationDomain::BufferAdaptor &bufferAdaptor, Akonadi2::Storage::Transaction &transaction); + + ResultSet query(const Akonadi2::Query &query, QSet &appliedFilters, Akonadi2::Storage::Transaction &transaction); + +private: + QByteArray mType; + QByteArrayList mProperties; + QHash > mIndexer; +}; + -- cgit v1.2.3