Akonadi

itemlinkhandler.cpp
1 /*
2  SPDX-FileCopyrightText: 2008 Volker Krause <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "itemlinkhandler.h"
8 
9 #include "akonadiserver_debug.h"
10 #include "connection.h"
11 #include "handlerhelper.h"
12 #include "storage/collectionqueryhelper.h"
13 #include "storage/datastore.h"
14 #include "storage/itemqueryhelper.h"
15 #include "storage/selectquerybuilder.h"
16 #include "storage/transaction.h"
17 
18 #include <private/scope_p.h>
19 
20 using namespace Akonadi;
21 using namespace Akonadi::Server;
22 
23 ItemLinkHandler::ItemLinkHandler(AkonadiServer &akonadi)
24  : Handler(akonadi)
25 {
26 }
27 
28 bool ItemLinkHandler::parseStream()
29 {
30  const auto &cmd = Protocol::cmdCast<Protocol::LinkItemsCommand>(m_command);
31 
32  const Collection collection = HandlerHelper::collectionFromScope(cmd.destination(), connection()->context());
33  if (!collection.isVirtual()) {
34  return failureResponse(QStringLiteral("Can't link items to non-virtual collections"));
35  }
36 
37  /* FIXME BIN
38  Resource originalContext;
39  Scope::SelectionScope itemSelectionScope = Scope::selectionScopeFromByteArray(m_streamParser->peekString());
40  if (itemSelectionScope != Scope::None) {
41  m_streamParser->readString();
42  // Unset Resource context if destination collection is specified using HRID/RID,
43  // because otherwise the Resource context is relative to the destination collection
44  // instead of the source collection (collection context)
45  if ((mDestinationScope.scope() == Scope::HierarchicalRid || mDestinationScope.scope() == Scope::Rid) && itemSelectionScope == Scope::Rid) {
46  originalContext = connection()->context()->resource();
47  connection()->context()->setResource(Resource());
48  }
49  }
50  Scope itemScope(itemSelectionScope);
51  itemScope.parseScope(m_streamParser);
52  */
53 
55  ItemQueryHelper::scopeToQuery(cmd.items(), connection()->context(), qb);
56 
57  /*
58  if (originalContext.isValid()) {
59  connection()->context()->setResource(originalContext);
60  }
61  */
62 
63  if (!qb.exec()) {
64  return failureResponse(QStringLiteral("Unable to execute item query"));
65  }
66 
67  const PimItem::List items = qb.result();
68  const bool createLinks = (cmd.action() == Protocol::LinkItemsCommand::Link);
69 
70  DataStore *store = connection()->storageBackend();
71  Transaction transaction(store, createLinks ? QStringLiteral("LINK") : QStringLiteral("UNLINK"));
72 
73  PimItem::List toLink;
74  PimItem::List toUnlink;
75  for (const PimItem &item : items) {
76  const bool alreadyLinked = collection.relatesToPimItem(item);
77  bool result = true;
78  if (createLinks && !alreadyLinked) {
79  result = collection.addPimItem(item);
80  toLink << item;
81  } else if (!createLinks && alreadyLinked) {
82  result = collection.removePimItem(item);
83  toUnlink << item;
84  }
85  if (!result) {
86  return failureResponse(QStringLiteral("Failed to modify item reference"));
87  }
88  }
89 
90  if (!transaction.commit()) {
91  return failureResponse(QStringLiteral("Cannot commit transaction."));
92  }
93 
94  if (!toLink.isEmpty()) {
95  store->notificationCollector()->itemsLinked(toLink, collection);
96  } else if (!toUnlink.isEmpty()) {
97  store->notificationCollector()->itemsUnlinked(toUnlink, collection);
98  }
99 
100  return successResponse<Protocol::LinkItemsResponse>();
101 }
NotificationCollector * notificationCollector()
Returns the notification collector of this DataStore object.
Definition: datastore.cpp:206
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
QVector< T > result()
Returns the result of this SELECT query.
bool exec()
Executes the query, returns true on success.
void itemsLinked(const PimItem::List &items, const Collection &collection)
Notify about linked items.
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
void itemsUnlinked(const PimItem::List &items, const Collection &collection)
Notify about unlinked items.
bool commit()
Commits the transaction.
Definition: transaction.cpp:29
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.