]>
Commit | Line | Data |
---|---|---|
8a8f9fb3 AM |
1 | From 9734074267bacd39aeb29c7a0d7df7cadb212d89 Mon Sep 17 00:00:00 2001 |
2 | From: =?UTF-8?q?Dan=20Vr=C3=A1til?= <dvratil@redhat.com> | |
3 | Date: Fri, 11 Jul 2014 18:33:39 +0200 | |
4 | Subject: [PATCH 03/30] STORE: Allow modifying items tags via Tag RID or GID | |
5 | ||
6 | Tags RID is of course allowed only to resources | |
7 | ||
8 | (Cherry-picked from 1a619d4df010a4862621a03031176ad8759070d3) | |
9 | ||
10 | Conflicts: | |
11 | CMakeLists.txt | |
12 | --- | |
13 | libs/protocol_p.h | 2 ++ | |
14 | server/src/handler/store.cpp | 76 ++++++++++++++++++++++++++++++-------------- | |
15 | server/src/handler/store.h | 8 +++-- | |
16 | server/src/handlerhelper.cpp | 4 +-- | |
17 | 4 files changed, 62 insertions(+), 28 deletions(-) | |
18 | ||
19 | diff --git a/libs/protocol_p.h b/libs/protocol_p.h | |
20 | index 002abe4..2ec2a2e 100644 | |
21 | --- a/libs/protocol_p.h | |
22 | +++ b/libs/protocol_p.h | |
23 | @@ -110,6 +110,7 @@ | |
24 | #define AKONADI_PARAM_TAGS "TAGS" | |
25 | #define AKONADI_PARAM_FULLPAYLOAD "FULLPAYLOAD" | |
26 | #define AKONADI_PARAM_GID "GID" | |
27 | +#define AKONADI_PARAM_GTAGS "GTAGS" | |
28 | #define AKONADI_PARAM_IGNOREERRORS "IGNOREERRORS" | |
29 | #define AKONADI_PARAM_INDEX "INDEX" | |
30 | #define AKONADI_PARAM_INHERIT "INHERIT" | |
31 | @@ -137,6 +138,7 @@ | |
32 | #define AKONADI_PARAM_REMOTEREVISION "REMOTEREVISION" | |
33 | #define AKONADI_PARAM_RESOURCE "RESOURCE" | |
34 | #define AKONADI_PARAM_REVISION "REV" | |
35 | +#define AKONADI_PARAM_RTAGS "RTAGS" | |
36 | #define AKONADI_PARAM_SILENT "SILENT" | |
37 | #define AKONADI_PARAM_DOT_SILENT ".SILENT" | |
38 | #define AKONADI_PARAM_CAPABILITY_SERVERSEARCH "SERVERSEARCH" | |
39 | diff --git a/server/src/handler/store.cpp b/server/src/handler/store.cpp | |
40 | index 6664a09..4a503a2 100644 | |
41 | --- a/server/src/handler/store.cpp | |
42 | +++ b/server/src/handler/store.cpp | |
43 | @@ -115,35 +115,56 @@ bool Store::deleteFlags( const PimItem::List &items, const QVector<QByteArray> & | |
44 | return true; | |
45 | } | |
46 | ||
47 | -bool Store::replaceTags( const PimItem::List &item, const ImapSet &tags ) | |
48 | +bool Store::replaceTags( const PimItem::List &item, const Tag::List &tags ) | |
49 | { | |
50 | - const Tag::List tagList = HandlerHelper::resolveTags( tags ); | |
51 | - if ( !connection()->storageBackend()->setItemsTags( item, tagList ) ) { | |
52 | + if ( !connection()->storageBackend()->setItemsTags( item, tags ) ) { | |
53 | throw HandlerException( "Store::replaceTags: Unable to set new item tags" ); | |
54 | } | |
55 | return true; | |
56 | } | |
57 | ||
58 | -bool Store::addTags( const PimItem::List &items, const ImapSet &tags, bool &tagsChanged ) | |
59 | +bool Store::addTags( const PimItem::List &items, const Tag::List &tags, bool &tagsChanged ) | |
60 | { | |
61 | - const Tag::List tagList = HandlerHelper::resolveTags( tags ); | |
62 | - if ( !connection()->storageBackend()->appendItemsTags( items, tagList, &tagsChanged ) ) { | |
63 | + if ( !connection()->storageBackend()->appendItemsTags( items, tags, &tagsChanged ) ) { | |
64 | akDebug() << "Store::addTags: Unable to add new item tags"; | |
65 | return false; | |
66 | } | |
67 | return true; | |
68 | } | |
69 | ||
70 | -bool Store::deleteTags( const PimItem::List &items, const ImapSet &tags ) | |
71 | +bool Store::deleteTags( const PimItem::List &items, const Tag::List &tags ) | |
72 | { | |
73 | - const Tag::List tagList = HandlerHelper::resolveTags( tags ); | |
74 | - if ( !connection()->storageBackend()->removeItemsTags( items, tagList ) ) { | |
75 | + if ( !connection()->storageBackend()->removeItemsTags( items, tags ) ) { | |
76 | akDebug() << "Store::deleteTags: Unable to remove item tags"; | |
77 | return false; | |
78 | } | |
79 | return true; | |
80 | } | |
81 | ||
82 | +bool Store::processTagsChange( Store::Operation op, const PimItem::List &items, | |
83 | + const Tag::List &tags, QSet<QByteArray> &changes ) | |
84 | +{ | |
85 | + bool tagsChanged = true; | |
86 | + if ( op == Replace ) { | |
87 | + tagsChanged = replaceTags( items, tags ); | |
88 | + } else if ( op == Add ) { | |
89 | + if ( !addTags( items, tags, tagsChanged ) ) { | |
90 | + return failureResponse( "Unable to add item tags." ); | |
91 | + } | |
92 | + } else if ( op == Delete ) { | |
93 | + if ( !( tagsChanged = deleteTags( items, tags ) ) ) { | |
94 | + return failureResponse( "Unable to remove item tags." ); | |
95 | + } | |
96 | + } | |
97 | + | |
98 | + if ( tagsChanged && !changes.contains( AKONADI_PARAM_TAGS ) ) { | |
99 | + changes << AKONADI_PARAM_TAGS; | |
100 | + } | |
101 | + | |
102 | + return true; | |
103 | +} | |
104 | + | |
105 | + | |
106 | bool Store::parseStream() | |
107 | { | |
108 | parseCommand(); | |
109 | @@ -234,22 +255,31 @@ bool Store::parseStream() | |
110 | } | |
111 | ||
112 | if ( command == AKONADI_PARAM_TAGS ) { | |
113 | - bool tagsChanged = true; | |
114 | - const ImapSet tags = m_streamParser->readSequenceSet(); | |
115 | - if ( op == Replace ) { | |
116 | - tagsChanged = replaceTags( pimItems, tags ); | |
117 | - } else if ( op == Add ) { | |
118 | - if ( !addTags( pimItems, tags, tagsChanged ) ) { | |
119 | - return failureResponse( "Unable to add item tags." ); | |
120 | - } | |
121 | - } else if ( op == Delete ) { | |
122 | - if ( !( tagsChanged = deleteTags( pimItems, tags ) ) ) { | |
123 | - return failureResponse( "Unable to remove item tags." ); | |
124 | - } | |
125 | + const ImapSet tagsIds = m_streamParser->readSequenceSet(); | |
126 | + const Tag::List tags = HandlerHelper::resolveTags( tagsIds ); | |
127 | + if (!processTagsChange( op, pimItems, tags, changes )) { | |
128 | + return false; | |
129 | } | |
130 | + continue; | |
131 | + } | |
132 | + | |
133 | + if ( command == AKONADI_PARAM_RTAGS ) { | |
134 | + if (!connection()->context()->resource().isValid()) { | |
135 | + throw HandlerException( "Only resources can use RTAGS" ); | |
136 | + } | |
137 | + const QVector<QByteArray> tagsIds = m_streamParser->readParenthesizedList().toVector(); | |
138 | + const Tag::List tags = HandlerHelper::resolveTagsByRID( tagsIds, connection()->context() ); | |
139 | + if (!processTagsChange( op, pimItems, tags, changes )) { | |
140 | + return false; | |
141 | + } | |
142 | + continue; | |
143 | + } | |
144 | ||
145 | - if ( tagsChanged && !changes.contains( AKONADI_PARAM_TAGS ) ) { | |
146 | - changes << AKONADI_PARAM_TAGS; | |
147 | + if ( command == AKONADI_PARAM_GTAGS ) { | |
148 | + const QVector<QByteArray> tagsIds = m_streamParser->readParenthesizedList().toVector(); | |
149 | + const Tag::List tags = HandlerHelper::resolveTagsByGID( tagsIds ); | |
150 | + if (!processTagsChange( op, pimItems, tags, changes )) { | |
151 | + return false; | |
152 | } | |
153 | continue; | |
154 | } | |
155 | diff --git a/server/src/handler/store.h b/server/src/handler/store.h | |
156 | index ad3a5a0..c618a53 100644 | |
157 | --- a/server/src/handler/store.h | |
158 | +++ b/server/src/handler/store.h | |
159 | @@ -115,12 +115,14 @@ class Store : public Handler | |
160 | bool replaceFlags( const PimItem::List &items, const QVector<QByteArray> &flags ); | |
161 | bool addFlags( const PimItem::List &items, const QVector<QByteArray> &flags, bool &flagsChanged ); | |
162 | bool deleteFlags( const PimItem::List &items, const QVector<QByteArray> &flags ); | |
163 | - bool replaceTags( const PimItem::List &items, const ImapSet &tags ); | |
164 | - bool addTags( const PimItem::List &items, const ImapSet &tags, bool &tagsChanged ); | |
165 | - bool deleteTags( const PimItem::List &items, const ImapSet &tags ); | |
166 | + bool replaceTags( const PimItem::List &items, const Tag::List &tags ); | |
167 | + bool addTags( const PimItem::List &items, const Tag::List &tags, bool &tagsChanged ); | |
168 | + bool deleteTags( const PimItem::List &items, const Tag::List &tags ); | |
169 | bool setGid( const PimItem &item, const QString &gid ); | |
170 | void sendPimItemResponse( const PimItem &pimItem ); | |
171 | ||
172 | + bool processTagsChange(Store::Operation operation, const PimItem::List &items, const Tag::List &tags, QSet<QByteArray> &changes); | |
173 | + | |
174 | private: | |
175 | Scope mScope; | |
176 | int mPos; | |
177 | diff --git a/server/src/handlerhelper.cpp b/server/src/handlerhelper.cpp | |
178 | index 763ea30..634a26c 100644 | |
179 | --- a/server/src/handlerhelper.cpp | |
180 | +++ b/server/src/handlerhelper.cpp | |
181 | @@ -366,7 +366,7 @@ Tag::List HandlerHelper::resolveTagsByGID(const QVector<QByteArray> &tagsGIDs) | |
182 | } | |
183 | ||
184 | Q_FOREACH (const QByteArray &tagGID, tagsGIDs) { | |
185 | - Tag::List tags = Tag::retrieveFiltered(Tag::gidColumn(), tagGID); | |
186 | + Tag::List tags = Tag::retrieveFiltered(Tag::gidColumn(), QString::fromLatin1(tagGID)); | |
187 | Tag tag; | |
188 | if (tags.isEmpty()) { | |
189 | tag.setGid(QString::fromUtf8(tagGID)); | |
190 | @@ -413,7 +413,7 @@ Tag::List HandlerHelper::resolveTagsByRID(const QVector< QByteArray >& tagsRIDs, | |
191 | cond.addColumnCondition(Tag::idFullColumnName(), Query::Equals, TagRemoteIdResourceRelation::tagIdFullColumnName()); | |
192 | cond.addValueCondition(TagRemoteIdResourceRelation::resourceIdFullColumnName(), Query::Equals, context->resource().id()); | |
193 | qb.addJoin(QueryBuilder::LeftJoin, TagRemoteIdResourceRelation::tableName(), cond); | |
194 | - qb.addValueCondition(TagRemoteIdResourceRelation::remoteIdFullColumnName(), Query::Equals, tagRID); | |
195 | + qb.addValueCondition(TagRemoteIdResourceRelation::remoteIdFullColumnName(), Query::Equals, QString::fromLatin1(tagRID)); | |
196 | if (!qb.exec()) { | |
197 | throw HandlerException("Unable to resolve tags"); | |
198 | } | |
199 | -- | |
200 | 2.1.0 | |
201 |