Akonadi

itemlinkhandler.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 "itemlinkhandler.h"
21 
22 #include "connection.h"
23 #include "handlerhelper.h"
24 #include "storage/datastore.h"
25 #include "storage/itemqueryhelper.h"
26 #include "storage/transaction.h"
27 #include "storage/selectquerybuilder.h"
28 #include "storage/collectionqueryhelper.h"
29 #include "akonadiserver_debug.h"
30 
31 #include <private/scope_p.h>
32 
33 using namespace Akonadi;
34 using namespace Akonadi::Server;
35 
36 ItemLinkHandler::ItemLinkHandler(AkonadiServer &akonadi)
37  : Handler(akonadi)
38 {}
39 
40 bool ItemLinkHandler::parseStream()
41 {
42  const auto &cmd = Protocol::cmdCast<Protocol::LinkItemsCommand>(m_command);
43 
44  const Collection collection = HandlerHelper::collectionFromScope(cmd.destination(), connection()->context());
45  if (!collection.isVirtual()) {
46  return failureResponse(QStringLiteral("Can't link items to non-virtual collections"));
47  }
48 
49  /* FIXME BIN
50  Resource originalContext;
51  Scope::SelectionScope itemSelectionScope = Scope::selectionScopeFromByteArray(m_streamParser->peekString());
52  if (itemSelectionScope != Scope::None) {
53  m_streamParser->readString();
54  // Unset Resource context if destination collection is specified using HRID/RID,
55  // because otherwise the Resource context is relative to the destination collection
56  // instead of the source collection (collection context)
57  if ((mDestinationScope.scope() == Scope::HierarchicalRid || mDestinationScope.scope() == Scope::Rid) && itemSelectionScope == Scope::Rid) {
58  originalContext = connection()->context()->resource();
59  connection()->context()->setResource(Resource());
60  }
61  }
62  Scope itemScope(itemSelectionScope);
63  itemScope.parseScope(m_streamParser);
64  */
65 
67  ItemQueryHelper::scopeToQuery(cmd.items(), connection()->context(), qb);
68 
69  /*
70  if (originalContext.isValid()) {
71  connection()->context()->setResource(originalContext);
72  }
73  */
74 
75  if (!qb.exec()) {
76  return failureResponse(QStringLiteral("Unable to execute item query"));
77  }
78 
79  const PimItem::List items = qb.result();
80  const bool createLinks = (cmd.action() == Protocol::LinkItemsCommand::Link);
81 
82  DataStore *store = connection()->storageBackend();
83  Transaction transaction(store, createLinks ? QStringLiteral("LINK") : QStringLiteral("UNLINK"));
84 
85  PimItem::List toLink, toUnlink;
86  for (const PimItem &item : items) {
87  const bool alreadyLinked = collection.relatesToPimItem(item);
88  bool result = true;
89  if (createLinks && !alreadyLinked) {
90  result = collection.addPimItem(item);
91  toLink << item;
92  } else if (!createLinks && alreadyLinked) {
93  result = collection.removePimItem(item);
94  toUnlink << item;
95  }
96  if (!result) {
97  return failureResponse(QStringLiteral("Failed to modify item reference"));
98  }
99  }
100 
101  if (!transaction.commit()) {
102  return failureResponse(QStringLiteral("Cannot commit transaction."));
103  }
104 
105  if (!toLink.isEmpty()) {
106  store->notificationCollector()->itemsLinked(toLink, collection);
107  } else if (!toUnlink.isEmpty()) {
108  store->notificationCollector()->itemsUnlinked(toUnlink, collection);
109  }
110 
111 
112  return successResponse<Protocol::LinkItemsResponse>();
113 }
NotificationCollector * notificationCollector()
Returns the notification collector of this DataStore object.
Definition: datastore.cpp:226
The handler interfaces describes an entity capable of handling an AkonadiIMAP command.
Definition: handler.h:48
void itemsUnlinked(const PimItem::List &items, const Collection &collection)
Notify about unlinked items.
Represents a collection of PIM items.
Definition: collection.h:76
void itemsLinked(const PimItem::List &items, const Collection &collection)
Notify about linked items.
Helper class for DataStore transaction handling.
Definition: transaction.h:37
QVector< T > result()
Returns the result of this SELECT query.
bool commit()
Commits the transaction.
Definition: transaction.cpp:42
Helper class for creating and executing database SELECT queries.
Helper integration between Akonadi and Qt.
This class handles all the database access.
Definition: datastore.h:108
bool exec()
Executes the query, returns true on success.
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Jun 5 2020 23:08:55 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.