Akonadi

collectioncopyhandler.cpp
1 /*
2  SPDX-FileCopyrightText: 2008 Volker Krause <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "collectioncopyhandler.h"
8 
9 #include "akonadi.h"
10 #include "cachecleaner.h"
11 #include "connection.h"
12 #include "handlerhelper.h"
13 #include "protocol_p.h"
14 #include "shared/akranges.h"
15 #include "storage/collectionqueryhelper.h"
16 #include "storage/datastore.h"
17 #include "storage/itemretriever.h"
18 #include "storage/transaction.h"
19 
20 using namespace Akonadi;
21 using namespace Akonadi::Server;
22 using namespace AkRanges;
23 
24 CollectionCopyHandler::CollectionCopyHandler(AkonadiServer &akonadi)
25  : ItemCopyHandler(akonadi)
26 {
27 }
28 
29 bool CollectionCopyHandler::copyCollection(const Collection &source, const Collection &target)
30 {
31  if (!CollectionQueryHelper::canBeMovedTo(source, target)) {
32  // We don't accept source==target, or source being an ancestor of target.
33  return false;
34  }
35 
36  // copy the source collection
37  Collection col = source;
38  col.setParentId(target.id());
39  col.setResourceId(target.resourceId());
40  // clear remote id and revision on inter-resource copies
41  if (source.resourceId() != target.resourceId()) {
42  col.setRemoteId(QString());
44  }
45 
46  const auto mimeTypes = source.mimeTypes() | Views::transform(&MimeType::name) | Actions::toQList;
47  const auto attributes = source.attributes() | Views::transform([](const auto &attr) {
48  return std::make_pair(attr.type(), attr.value());
49  })
50  | Actions::toQMap;
51 
52  if (!storageBackend()->appendCollection(col, mimeTypes, attributes)) {
53  return false;
54  }
55 
56  // copy sub-collections
57  const Collection::List lstCols = source.children();
58  for (const Collection &child : lstCols) {
59  if (!copyCollection(child, col)) {
60  return false;
61  }
62  }
63 
64  // copy items
65  const auto items = source.items();
66  for (const auto &item : items) {
67  if (!copyItem(item, col)) {
68  return false;
69  }
70  }
71 
72  return true;
73 }
74 
75 bool CollectionCopyHandler::parseStream()
76 {
77  const auto &cmd = Protocol::cmdCast<Protocol::CopyCollectionCommand>(m_command);
78 
79  const Collection source = HandlerHelper::collectionFromScope(cmd.collection(), connection()->context());
80  if (!source.isValid()) {
81  return failureResponse(QStringLiteral("No valid source specified"));
82  }
83 
84  const Collection target = HandlerHelper::collectionFromScope(cmd.destination(), connection()->context());
85  if (!target.isValid()) {
86  return failureResponse(QStringLiteral("No valid target specified"));
87  }
88 
89  CacheCleanerInhibitor inhibitor(akonadi());
90 
91  // retrieve all not yet cached items of the source
92  ItemRetriever retriever(akonadi().itemRetrievalManager(), connection(), connection()->context());
93  retriever.setCollection(source, true);
94  retriever.setRetrieveFullPayload(true);
95  if (!retriever.exec()) {
96  return failureResponse(retriever.lastError());
97  }
98 
99  Transaction transaction(storageBackend(), QStringLiteral("CollectionCopyHandler"));
100 
101  if (!copyCollection(source, target)) {
102  return failureResponse(QStringLiteral("Failed to copy collection"));
103  }
104 
105  if (!transaction.commit()) {
106  return failureResponse(QStringLiteral("Cannot commit transaction."));
107  }
108 
109  return successResponse<Protocol::CopyCollectionResponse>();
110 }
Helper class for DataStore transaction handling.
Definition: transaction.h:22
Attribute::List attributes() const
Returns a list of all attributes of the collection.
Definition: collection.cpp:166
Represents a collection of PIM items.
Definition: collection.h:61
A RAII helper class to temporarily stop the CacheCleaner.
Definition: cachecleaner.h:31
void setCollection(const Collection &collection, bool recursive=true)
Retrieve all items in the given collection.
void setRemoteId(const QString &id)
Sets the remote id of the collection.
Definition: collection.cpp:101
QStringList mimeTypes(Mode mode=Writing)
Helper class for retrieving missing items parts from remote resources.
Definition: itemretriever.h:38
bool commit()
Commits the transaction.
Definition: transaction.cpp:29
void setRemoteRevision(const QString &revision)
Sets the remote revision of the collection.
Definition: collection.cpp:111
Helper integration between Akonadi and Qt.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Jul 2 2022 06:41:47 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.