Akonadi

itemcopyhandler.cpp
1 /*
2  SPDX-FileCopyrightText: 2008 Volker Krause <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "itemcopyhandler.h"
8 
9 #include "akonadi.h"
10 #include "cachecleaner.h"
11 #include "connection.h"
12 #include "handlerhelper.h"
13 #include "storage/datastore.h"
14 #include "storage/itemqueryhelper.h"
15 #include "storage/itemretriever.h"
16 #include "storage/parthelper.h"
17 #include "storage/selectquerybuilder.h"
18 #include "storage/transaction.h"
19 
20 #include <private/imapset_p.h>
21 
22 using namespace Akonadi;
23 using namespace Akonadi::Server;
24 
25 ItemCopyHandler::ItemCopyHandler(AkonadiServer &akonadi)
26  : Handler(akonadi)
27 {
28 }
29 
30 bool ItemCopyHandler::copyItem(const PimItem &item, const Collection &target)
31 {
32  PimItem newItem = item;
33  newItem.setId(-1);
34  newItem.setRev(0);
35  newItem.setDatetime(QDateTime::currentDateTimeUtc());
36  newItem.setAtime(QDateTime::currentDateTimeUtc());
37  newItem.setRemoteId(QString());
38  newItem.setRemoteRevision(QString());
39  newItem.setCollectionId(target.id());
40  Part::List newParts;
41  const auto parts = item.parts();
42  newParts.reserve(parts.size());
43  for (const Part &part : parts) {
44  Part newPart(part);
45  newPart.setData(PartHelper::translateData(newPart.data(), part.storage()));
46  newPart.setPimItemId(-1);
47  newPart.setStorage(Part::Internal);
48  newParts << newPart;
49  }
50 
51  DataStore *store = connection()->storageBackend();
52  return store->appendPimItem(newParts, item.flags(), item.mimeType(), target, QDateTime::currentDateTimeUtc(), QString(), QString(), item.gid(), newItem);
53 }
54 
55 void ItemCopyHandler::processItems(const QVector<qint64> &ids)
56 {
58  ItemQueryHelper::itemSetToQuery(ImapSet(ids), qb);
59  if (!qb.exec()) {
60  failureResponse(QStringLiteral("Unable to retrieve items"));
61  return;
62  }
63  const PimItem::List items = qb.result();
64  qb.query().finish();
65 
66  DataStore *store = connection()->storageBackend();
67  Transaction transaction(store, QStringLiteral("COPY"));
68 
69  for (const PimItem &item : items) {
70  if (!copyItem(item, mTargetCollection)) {
71  failureResponse(QStringLiteral("Unable to copy item"));
72  return;
73  }
74  }
75 
76  if (!transaction.commit()) {
77  failureResponse(QStringLiteral("Cannot commit transaction."));
78  return;
79  }
80 }
81 
82 bool ItemCopyHandler::parseStream()
83 {
84  const auto &cmd = Protocol::cmdCast<Protocol::CopyItemsCommand>(m_command);
85 
86  if (!checkScopeConstraints(cmd.items(), Scope::Uid)) {
87  return failureResponse(QStringLiteral("Only UID copy is allowed"));
88  }
89 
90  if (cmd.items().isEmpty()) {
91  return failureResponse(QStringLiteral("No items specified"));
92  }
93 
94  mTargetCollection = HandlerHelper::collectionFromScope(cmd.destination(), connection()->context());
95  if (!mTargetCollection.isValid()) {
96  return failureResponse(QStringLiteral("No valid target specified"));
97  }
98  if (mTargetCollection.isVirtual()) {
99  return failureResponse(QStringLiteral("Copying items into virtual collections is not allowed"));
100  }
101 
102  CacheCleanerInhibitor inhibitor(akonadi());
103 
104  ItemRetriever retriever(akonadi().itemRetrievalManager(), connection(), connection()->context());
105  retriever.setItemSet(cmd.items().uidSet());
106  retriever.setRetrieveFullPayload(true);
107  QObject::connect(&retriever, &ItemRetriever::itemsRetrieved, [this](const QVector<qint64> &ids) {
108  processItems(ids);
109  });
110  if (!retriever.exec()) {
111  return failureResponse(retriever.lastError());
112  }
113 
114  return successResponse<Protocol::CopyItemsResponse>();
115 }
This class handles all the database access.
Definition: datastore.h:94
Helper class for DataStore transaction handling.
Definition: transaction.h:22
Represents a collection of PIM items.
Definition: collection.h:61
A RAII helper class to temporarily stop the CacheCleaner.
Definition: cachecleaner.h:31
QDateTime currentDateTimeUtc()
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QVector< T > result()
Returns the result of this SELECT query.
void finish()
bool exec()
Executes the query, returns true on success.
Helper class for creating and executing database SELECT queries.
The handler interfaces describes an entity capable of handling an AkonadiIMAP command.
Definition: handler.h:39
Helper class for retrieving missing items parts from remote resources.
Definition: itemretriever.h:38
QSqlQuery & query()
Returns the query, only valid after exec().
Helper integration between Akonadi and Qt.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Jun 30 2022 03:51:46 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.