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