Akonadi

collectioncopyhandler.cpp
1 /*
2  Copyright (c) 2008 Volker Krause <[email protected]>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #include "collectioncopyhandler.h"
21 
22 #include "akonadi.h"
23 #include "connection.h"
24 #include "handler/itemcopyhandler.h"
25 #include "handlerhelper.h"
26 #include "cachecleaner.h"
27 #include "protocol_p.h"
28 #include "storage/datastore.h"
29 #include "storage/transaction.h"
30 #include "storage/itemretriever.h"
31 #include "storage/collectionqueryhelper.h"
32 #include "shared/akranges.h"
33 
34 using namespace Akonadi;
35 using namespace Akonadi::Server;
36 using namespace AkRanges;
37 
38 CollectionCopyHandler::CollectionCopyHandler(AkonadiServer &akonadi)
39  : ItemCopyHandler(akonadi)
40 {}
41 
42 bool CollectionCopyHandler::copyCollection(const Collection &source, const Collection &target)
43 {
44  if (!CollectionQueryHelper::canBeMovedTo(source, target)) {
45  // We don't accept source==target, or source being an ancestor of target.
46  return false;
47  }
48 
49  // copy the source collection
50  Collection col = source;
51  col.setParentId(target.id());
52  col.setResourceId(target.resourceId());
53  // clear remote id and revision on inter-resource copies
54  if (source.resourceId() != target.resourceId()) {
55  col.setRemoteId(QString());
57  }
58 
59  const auto mimeTypes = source.mimeTypes() | Views::transform(&MimeType::name) | Actions::toQList;
60  const auto attributes = source.attributes() | Views::transform([](const auto &attr) { return std::make_pair(attr.type(), attr.value()); }) | Actions::toQMap;
61 
62  if (!storageBackend()->appendCollection(col, mimeTypes, attributes)) {
63  return false;
64  }
65 
66 
67  // copy sub-collections
68  const Collection::List lstCols = source.children();
69  for (const Collection &child : lstCols) {
70  if (!copyCollection(child, col)) {
71  return false;
72  }
73  }
74 
75  // copy items
76  const auto items = source.items();
77  for (const auto &item : items) {
78  if (!copyItem(item, col)) {
79  return false;
80  }
81  }
82 
83  return true;
84 }
85 
86 bool CollectionCopyHandler::parseStream()
87 {
88  const auto &cmd = Protocol::cmdCast<Protocol::CopyCollectionCommand>(m_command);
89 
90  const Collection source = HandlerHelper::collectionFromScope(cmd.collection(), connection()->context());
91  if (!source.isValid()) {
92  return failureResponse(QStringLiteral("No valid source specified"));
93  }
94 
95  const Collection target = HandlerHelper::collectionFromScope(cmd.destination(), connection()->context());
96  if (!target.isValid()) {
97  return failureResponse(QStringLiteral("No valid target specified"));
98  }
99 
100  CacheCleanerInhibitor inhibitor(akonadi());
101 
102  // retrieve all not yet cached items of the source
103  ItemRetriever retriever(akonadi().itemRetrievalManager(), connection(), connection()->context());
104  retriever.setCollection(source, true);
105  retriever.setRetrieveFullPayload(true);
106  if (!retriever.exec()) {
107  return failureResponse(retriever.lastError());
108  }
109 
110  Transaction transaction(storageBackend(), QStringLiteral("CollectionCopyHandler"));
111 
112  if (!copyCollection(source, target)) {
113  return failureResponse(QStringLiteral("Failed to copy collection"));
114  }
115 
116  if (!transaction.commit()) {
117  return failureResponse(QStringLiteral("Cannot commit transaction."));
118  }
119 
120  return successResponse<Protocol::CopyCollectionResponse>();
121 }
void setCollection(const Collection &collection, bool recursive=true)
Retrieve all items in the given collection.
Helper class for retrieving missing items parts from remote resources.
Definition: itemretriever.h:53
Represents a collection of PIM items.
Definition: collection.h:76
A RAII helper class to temporarily stop the CacheCleaner.
Definition: cachecleaner.h:46
void setRemoteId(const QString &id)
Sets the remote id of the collection.
Definition: collection.cpp:117
Attribute::List attributes() const
Returns a list of all attributes of the collection.
Definition: collection.cpp:182
Helper class for DataStore transaction handling.
Definition: transaction.h:37
void setRemoteRevision(const QString &revision)
Sets the remote revision of the collection.
Definition: collection.cpp:127
QStringList mimeTypes(Types)
Handler for the COPY command.
Id id() const
Returns the unique identifier of the collection.
Definition: collection.cpp:112
Helper integration between Akonadi and Qt.
Representation of a record in the Collection table.
Definition: entities.h:451
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon May 25 2020 22:46:08 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.