Blob Blame History Raw
From 9734074267bacd39aeb29c7a0d7df7cadb212d89 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20Vr=C3=A1til?= <dvratil@redhat.com>
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<QByteArray> &
   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<QByteArray> &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<QByteArray> 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<QByteArray> 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<QByteArray> &flags );
     bool addFlags( const PimItem::List &items, const QVector<QByteArray> &flags, bool &flagsChanged );
     bool deleteFlags( const PimItem::List &items, const QVector<QByteArray> &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<QByteArray> &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<QByteArray> &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