Akonadi

collectioncopyhandler.cpp
1/*
2 SPDX-FileCopyrightText: 2008 Volker Krause <vkrause@kde.org>
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
20using namespace Akonadi;
21using namespace Akonadi::Server;
22using namespace AkRanges;
23
24CollectionCopyHandler::CollectionCopyHandler(AkonadiServer &akonadi)
25 : ItemCopyHandler(akonadi)
26{
27}
28
29bool 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
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}
Represents a collection of PIM items.
Definition collection.h:62
Attribute::List attributes() const
Returns a list of all attributes of the collection.
void setRemoteId(const QString &id)
Sets the remote id of the collection.
void setRemoteRevision(const QString &revision)
Sets the remote revision of the collection.
A RAII helper class to temporarily stop the CacheCleaner.
bool parseStream() override
Parse and handle the IMAP message using the streaming parser.
Handler for the COPY command.
bool copyItem(const PimItem &item, const Collection &target)
Copy the given item and all its parts into the target.
Helper class for retrieving missing items parts from remote resources.
void setCollection(const Collection &collection, bool recursive=true)
Retrieve all items in the given collection.
Helper class for DataStore transaction handling.
Definition transaction.h:23
bool commit()
Commits the transaction.
bool canBeMovedTo(const Collection &collection, const Collection &parent)
Checks if a collection could be moved from its current parent into the given one.
Helper integration between Akonadi and Qt.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:13:38 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.