1 /*
2  Copyright (c) 2008 Volker Krause <[email protected]>
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.
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.
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 */
20 #include "itemcopyhandler.h"
22 #include "akonadi.h"
23 #include "connection.h"
24 #include "handlerhelper.h"
25 #include "cachecleaner.h"
26 #include "storage/datastore.h"
27 #include "storage/itemqueryhelper.h"
28 #include "storage/itemretriever.h"
29 #include "storage/selectquerybuilder.h"
30 #include "storage/transaction.h"
31 #include "storage/parthelper.h"
33 #include <private/imapset_p.h>
35 using namespace Akonadi;
36 using namespace Akonadi::Server;
38 ItemCopyHandler::ItemCopyHandler(AkonadiServer &akonadi)
39  : Handler(akonadi)
40 {}
42 bool ItemCopyHandler::copyItem(const PimItem &item, const Collection &target)
43 {
44  PimItem newItem = item;
45  newItem.setId(-1);
46  newItem.setRev(0);
49  newItem.setRemoteId(QString());
50  newItem.setRemoteRevision(QString());
51  newItem.setCollectionId(target.id());
52  Part::List parts;
53  parts.reserve(item.parts().count());
54  Q_FOREACH (const Part &part, item.parts()) {
55  Part newPart(part);
56  newPart.setData(PartHelper::translateData(newPart.data(), part.storage()));
57  newPart.setPimItemId(-1);
58  newPart.setStorage(Part::Internal);
59  parts << newPart;
60  }
62  DataStore *store = connection()->storageBackend();
63  if (!store->appendPimItem(parts, item.flags(), item.mimeType(), target, QDateTime::currentDateTimeUtc(), QString(), QString(), item.gid(), newItem)) {
64  return false;
65  }
67  return true;
68 }
70 void ItemCopyHandler::processItems(const QVector<qint64> &ids)
71 {
73  ItemQueryHelper::itemSetToQuery(ImapSet(ids), qb);
74  if (!qb.exec()) {
75  failureResponse(QStringLiteral("Unable to retrieve items"));
76  return;
77  }
78  const PimItem::List items = qb.result();
79  qb.query().finish();
81  DataStore *store = connection()->storageBackend();
82  Transaction transaction(store, QStringLiteral("COPY"));
84  for (const PimItem &item : items) {
85  if (!copyItem(item, mTargetCollection)) {
86  failureResponse(QStringLiteral("Unable to copy item"));
87  return;
88  }
89  }
91  if (!transaction.commit()) {
92  failureResponse(QStringLiteral("Cannot commit transaction."));
93  return;
94  }
95 }
98 {
99  const auto &cmd = Protocol::cmdCast<Protocol::CopyItemsCommand>(m_command);
101  if (!checkScopeConstraints(cmd.items(), Scope::Uid)) {
102  return failureResponse(QStringLiteral("Only UID copy is allowed"));
103  }
105  if (cmd.items().isEmpty()) {
106  return failureResponse(QStringLiteral("No items specified"));
107  }
109  mTargetCollection = HandlerHelper::collectionFromScope(cmd.destination(), connection()->context());
110  if (!mTargetCollection.isValid()) {
111  return failureResponse(QStringLiteral("No valid target specified"));
112  }
113  if (mTargetCollection.isVirtual()) {
114  return failureResponse(QStringLiteral("Copying items into virtual collections is not allowed"));
115  }
117  CacheCleanerInhibitor inhibitor(akonadi());
119  ItemRetriever retriever(akonadi().itemRetrievalManager(), connection(), connection()->context());
120  retriever.setItemSet(cmd.items().uidSet());
121  retriever.setRetrieveFullPayload(true);
122  QObject::connect(&retriever, &ItemRetriever::itemsRetrieved,
123  [this](const QVector<qint64> &ids) {
124  processItems(ids);
125  });
126  if (!retriever.exec()) {
127  return failureResponse(retriever.lastError());
128  }
130  return successResponse<Protocol::CopyItemsResponse>();
131 }
void setCollectionId(qint64 collectionId)
Sets the value of the collectionId column of this record.
Definition: entities.cpp:4041
void setDatetime(const QDateTime &datetime)
Sets the value of the datetime column of this record.
Definition: entities.cpp:4067
QSqlQuery & query()
Returns the query, only valid after exec().
Helper class for retrieving missing items parts from remote resources.
Definition: itemretriever.h:53
void itemSetToQuery(const ImapSet &set, QueryBuilder &qb, const Collection &collection=Collection())
Add conditions to qb for the given item set set.
The handler interfaces describes an entity capable of handling an AkonadiIMAP command.
Definition: handler.h:48
void setPimItemId(qint64 pimItemId)
Sets the value of the pimItemId column of this record.
Definition: entities.cpp:6402
A RAII helper class to temporarily stop the CacheCleaner.
Definition: cachecleaner.h:46
Representation of a record in the Part table.
Definition: entities.h:1970
void setData(const QByteArray &data)
Sets the value of the data column of this record.
Definition: entities.cpp:6428
QByteArray translateData(const QByteArray &data, Part::Storage storageType)
Returns the payload data.
Definition: parthelper.cpp:136
bool copyItem(const PimItem &item, const Collection &target)
Copy the given item and all its parts into the target.
Helper class for DataStore transaction handling.
Definition: transaction.h:37
QVector< T > result()
Returns the result of this SELECT query.
QString gid() const
Returns the value of the gid column of this record.
Definition: entities.cpp:4022
bool commit()
Commits the transaction.
Definition: transaction.cpp:42
void setRemoteId(const QString &remoteId)
Sets the value of the remoteId column of this record.
Definition: entities.cpp:4002
void reserve(int size)
void setRemoteRevision(const QString &remoteRevision)
Sets the value of the remoteRevision column of this record.
Definition: entities.cpp:4015
QVector< Part > parts() const
Retrieve a list of all Part records referring to this record in their column pimItemId.
Definition: entities.cpp:4583
Helper class for creating and executing database SELECT queries.
Definition: item.h:44
QByteArray data() const
Returns the value of the data column of this record.
Definition: entities.cpp:6422
void finish()
Helper integration between Akonadi and Qt.
void setAtime(const QDateTime &atime)
Sets the value of the atime column of this record.
Definition: entities.cpp:4080
This class handles all the database access.
Definition: datastore.h:102
Part::Storage storage() const
Returns the value of the storage column of this record.
Definition: entities.cpp:6461
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
MimeType mimeType() const
Retrieve the MimeType record referred to by the mimeTypeId column of this record. ...
Definition: entities.cpp:4567
QDateTime currentDateTimeUtc()
void setRev(int rev)
Sets the value of the rev column of this record.
Definition: entities.cpp:3989
Representation of a record in the PimItem table.
Definition: entities.h:1194
void setStorage(Part::Storage storage)
Sets the value of the storage column of this record.
Definition: entities.cpp:6467
bool exec()
Executes the query, returns true on success.
bool parseStream() override
Parse and handle the IMAP message using the streaming parser.
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 Tue May 26 2020 22:46:20 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.