From 9734074267bacd39aeb29c7a0d7df7cadb212d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Vr=C3=A1til?= Date: Fri, 11 Jul 2014 18:33:39 +0200 Subject: [PATCH 03/30] STORE: Allow modifying items tags via Tag RID or GID Tags RID is of course allowed only to resources (Cherry-picked from 1a619d4df010a4862621a03031176ad8759070d3) Conflicts: CMakeLists.txt --- libs/protocol_p.h | 2 ++ server/src/handler/store.cpp | 76 ++++++++++++++++++++++++++++++-------------- server/src/handler/store.h | 8 +++-- server/src/handlerhelper.cpp | 4 +-- 4 files changed, 62 insertions(+), 28 deletions(-) diff --git a/libs/protocol_p.h b/libs/protocol_p.h index 002abe4..2ec2a2e 100644 --- a/libs/protocol_p.h +++ b/libs/protocol_p.h @@ -110,6 +110,7 @@ #define AKONADI_PARAM_TAGS "TAGS" #define AKONADI_PARAM_FULLPAYLOAD "FULLPAYLOAD" #define AKONADI_PARAM_GID "GID" +#define AKONADI_PARAM_GTAGS "GTAGS" #define AKONADI_PARAM_IGNOREERRORS "IGNOREERRORS" #define AKONADI_PARAM_INDEX "INDEX" #define AKONADI_PARAM_INHERIT "INHERIT" @@ -137,6 +138,7 @@ #define AKONADI_PARAM_REMOTEREVISION "REMOTEREVISION" #define AKONADI_PARAM_RESOURCE "RESOURCE" #define AKONADI_PARAM_REVISION "REV" +#define AKONADI_PARAM_RTAGS "RTAGS" #define AKONADI_PARAM_SILENT "SILENT" #define AKONADI_PARAM_DOT_SILENT ".SILENT" #define AKONADI_PARAM_CAPABILITY_SERVERSEARCH "SERVERSEARCH" diff --git a/server/src/handler/store.cpp b/server/src/handler/store.cpp index 6664a09..4a503a2 100644 --- a/server/src/handler/store.cpp +++ b/server/src/handler/store.cpp @@ -115,35 +115,56 @@ bool Store::deleteFlags( const PimItem::List &items, const QVector & return true; } -bool Store::replaceTags( const PimItem::List &item, const ImapSet &tags ) +bool Store::replaceTags( const PimItem::List &item, const Tag::List &tags ) { - const Tag::List tagList = HandlerHelper::resolveTags( tags ); - if ( !connection()->storageBackend()->setItemsTags( item, tagList ) ) { + if ( !connection()->storageBackend()->setItemsTags( item, tags ) ) { throw HandlerException( "Store::replaceTags: Unable to set new item tags" ); } return true; } -bool Store::addTags( const PimItem::List &items, const ImapSet &tags, bool &tagsChanged ) +bool Store::addTags( const PimItem::List &items, const Tag::List &tags, bool &tagsChanged ) { - const Tag::List tagList = HandlerHelper::resolveTags( tags ); - if ( !connection()->storageBackend()->appendItemsTags( items, tagList, &tagsChanged ) ) { + if ( !connection()->storageBackend()->appendItemsTags( items, tags, &tagsChanged ) ) { akDebug() << "Store::addTags: Unable to add new item tags"; return false; } return true; } -bool Store::deleteTags( const PimItem::List &items, const ImapSet &tags ) +bool Store::deleteTags( const PimItem::List &items, const Tag::List &tags ) { - const Tag::List tagList = HandlerHelper::resolveTags( tags ); - if ( !connection()->storageBackend()->removeItemsTags( items, tagList ) ) { + if ( !connection()->storageBackend()->removeItemsTags( items, tags ) ) { akDebug() << "Store::deleteTags: Unable to remove item tags"; return false; } return true; } +bool Store::processTagsChange( Store::Operation op, const PimItem::List &items, + const Tag::List &tags, QSet &changes ) +{ + bool tagsChanged = true; + if ( op == Replace ) { + tagsChanged = replaceTags( items, tags ); + } else if ( op == Add ) { + if ( !addTags( items, tags, tagsChanged ) ) { + return failureResponse( "Unable to add item tags." ); + } + } else if ( op == Delete ) { + if ( !( tagsChanged = deleteTags( items, tags ) ) ) { + return failureResponse( "Unable to remove item tags." ); + } + } + + if ( tagsChanged && !changes.contains( AKONADI_PARAM_TAGS ) ) { + changes << AKONADI_PARAM_TAGS; + } + + return true; +} + + bool Store::parseStream() { parseCommand(); @@ -234,22 +255,31 @@ bool Store::parseStream() } if ( command == AKONADI_PARAM_TAGS ) { - bool tagsChanged = true; - const ImapSet tags = m_streamParser->readSequenceSet(); - if ( op == Replace ) { - tagsChanged = replaceTags( pimItems, tags ); - } else if ( op == Add ) { - if ( !addTags( pimItems, tags, tagsChanged ) ) { - return failureResponse( "Unable to add item tags." ); - } - } else if ( op == Delete ) { - if ( !( tagsChanged = deleteTags( pimItems, tags ) ) ) { - return failureResponse( "Unable to remove item tags." ); - } + const ImapSet tagsIds = m_streamParser->readSequenceSet(); + const Tag::List tags = HandlerHelper::resolveTags( tagsIds ); + if (!processTagsChange( op, pimItems, tags, changes )) { + return false; } + continue; + } + + if ( command == AKONADI_PARAM_RTAGS ) { + if (!connection()->context()->resource().isValid()) { + throw HandlerException( "Only resources can use RTAGS" ); + } + const QVector tagsIds = m_streamParser->readParenthesizedList().toVector(); + const Tag::List tags = HandlerHelper::resolveTagsByRID( tagsIds, connection()->context() ); + if (!processTagsChange( op, pimItems, tags, changes )) { + return false; + } + continue; + } - if ( tagsChanged && !changes.contains( AKONADI_PARAM_TAGS ) ) { - changes << AKONADI_PARAM_TAGS; + if ( command == AKONADI_PARAM_GTAGS ) { + const QVector tagsIds = m_streamParser->readParenthesizedList().toVector(); + const Tag::List tags = HandlerHelper::resolveTagsByGID( tagsIds ); + if (!processTagsChange( op, pimItems, tags, changes )) { + return false; } continue; } diff --git a/server/src/handler/store.h b/server/src/handler/store.h index ad3a5a0..c618a53 100644 --- a/server/src/handler/store.h +++ b/server/src/handler/store.h @@ -115,12 +115,14 @@ class Store : public Handler bool replaceFlags( const PimItem::List &items, const QVector &flags ); bool addFlags( const PimItem::List &items, const QVector &flags, bool &flagsChanged ); bool deleteFlags( const PimItem::List &items, const QVector &flags ); - bool replaceTags( const PimItem::List &items, const ImapSet &tags ); - bool addTags( const PimItem::List &items, const ImapSet &tags, bool &tagsChanged ); - bool deleteTags( const PimItem::List &items, const ImapSet &tags ); + bool replaceTags( const PimItem::List &items, const Tag::List &tags ); + bool addTags( const PimItem::List &items, const Tag::List &tags, bool &tagsChanged ); + bool deleteTags( const PimItem::List &items, const Tag::List &tags ); bool setGid( const PimItem &item, const QString &gid ); void sendPimItemResponse( const PimItem &pimItem ); + bool processTagsChange(Store::Operation operation, const PimItem::List &items, const Tag::List &tags, QSet &changes); + private: Scope mScope; int mPos; diff --git a/server/src/handlerhelper.cpp b/server/src/handlerhelper.cpp index 763ea30..634a26c 100644 --- a/server/src/handlerhelper.cpp +++ b/server/src/handlerhelper.cpp @@ -366,7 +366,7 @@ Tag::List HandlerHelper::resolveTagsByGID(const QVector &tagsGIDs) } Q_FOREACH (const QByteArray &tagGID, tagsGIDs) { - Tag::List tags = Tag::retrieveFiltered(Tag::gidColumn(), tagGID); + Tag::List tags = Tag::retrieveFiltered(Tag::gidColumn(), QString::fromLatin1(tagGID)); Tag tag; if (tags.isEmpty()) { tag.setGid(QString::fromUtf8(tagGID)); @@ -413,7 +413,7 @@ Tag::List HandlerHelper::resolveTagsByRID(const QVector< QByteArray >& tagsRIDs, cond.addColumnCondition(Tag::idFullColumnName(), Query::Equals, TagRemoteIdResourceRelation::tagIdFullColumnName()); cond.addValueCondition(TagRemoteIdResourceRelation::resourceIdFullColumnName(), Query::Equals, context->resource().id()); qb.addJoin(QueryBuilder::LeftJoin, TagRemoteIdResourceRelation::tableName(), cond); - qb.addValueCondition(TagRemoteIdResourceRelation::remoteIdFullColumnName(), Query::Equals, tagRID); + qb.addValueCondition(TagRemoteIdResourceRelation::remoteIdFullColumnName(), Query::Equals, QString::fromLatin1(tagRID)); if (!qb.exec()) { throw HandlerException("Unable to resolve tags"); } -- 2.1.0