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