Akonadi

collectioncreatehandler.cpp
1 /***************************************************************************
2  * Copyright (C) 2006 by Ingo Kloecker <[email protected]> *
3  * *
4  * This program is free software; you can redistribute it and/or modify *
5  * it under the terms of the GNU Library General Public License as *
6  * published by the Free Software Foundation; either version 2 of the *
7  * License, or (at your option) any later version. *
8  * *
9  * This program is distributed in the hope that it will be useful, *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12  * GNU General Public License for more details. *
13  * *
14  * You should have received a copy of the GNU Library General Public *
15  * License along with this program; if not, write to the *
16  * Free Software Foundation, Inc., *
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18  ***************************************************************************/
19 #include "collectioncreatehandler.h"
20 
21 #include "connection.h"
22 #include "handlerhelper.h"
23 #include "storage/datastore.h"
24 #include "storage/transaction.h"
25 #include "storage/selectquerybuilder.h"
26 #include "shared/akranges.h"
27 
28 #include <private/scope_p.h>
29 
30 using namespace Akonadi;
31 using namespace Akonadi::Server;
32 using namespace AkRanges;
33 
34 CollectionCreateHandler::CollectionCreateHandler(AkonadiServer &akonadi)
35  : Handler(akonadi)
36 {}
37 
38 bool CollectionCreateHandler::parseStream()
39 {
40  const auto &cmd = Protocol::cmdCast<Protocol::CreateCollectionCommand>(m_command);
41 
42  if (cmd.name().isEmpty()) {
43  return failureResponse(QStringLiteral("Invalid collection name"));
44  }
45 
47  qint64 resourceId = 0;
48  bool forceVirtual = false;
49  MimeType::List parentContentTypes;
50 
51  // Invalid or empty scope means we refer to root collection
52  if (cmd.parent().scope() != Scope::Invalid && !cmd.parent().isEmpty()) {
53  parent = HandlerHelper::collectionFromScope(cmd.parent(), connection()->context());
54  if (!parent.isValid()) {
55  return failureResponse(QStringLiteral("Invalid parent collection"));
56  }
57 
58  // check if parent can contain a sub-folder
59  parentContentTypes = parent.mimeTypes();
60  const auto hasMimeType = [](const QString &mimeType) { return [mimeType](const MimeType &mt) { return mt.name() == mimeType; }; };
61  const bool canContainCollections = parentContentTypes | Actions::any(hasMimeType(CollectionMimeType));
62  const bool canContainVirtualCollections = parentContentTypes | Actions::any(hasMimeType(VirtualCollectionMimeType));
63 
64  if (!canContainCollections && !canContainVirtualCollections) {
65  return failureResponse(QStringLiteral("Parent collection can not contain sub-collections"));
66  }
67 
68  // If only virtual collections are supported, force every new collection to
69  // be virtual. Otherwise depend on VIRTUAL attribute in the command
70  if (canContainVirtualCollections && !canContainCollections) {
71  forceVirtual = true;
72  }
73 
74  // inherit resource
75  resourceId = parent.resourceId();
76  } else {
77  const QString sessionId = QString::fromUtf8(connection()->sessionId());
78  Resource res = Resource::retrieveByName(sessionId);
79  if (!res.isValid()) {
80  return failureResponse(QStringLiteral("Cannot create top-level collection"));
81  }
82  resourceId = res.id();
83  }
84 
85  Collection collection;
86  if (parent.isValid()) {
87  collection.setParentId(parent.id());
88  }
89  collection.setName(cmd.name());
90  collection.setResourceId(resourceId);
91  collection.setRemoteId(cmd.remoteId());
92  collection.setRemoteRevision(cmd.remoteRevision());
93  collection.setIsVirtual(cmd.isVirtual() || forceVirtual);
94  collection.setEnabled(cmd.enabled());
95  collection.setSyncPref(static_cast<Collection::Tristate>(cmd.syncPref()));
96  collection.setDisplayPref(static_cast<Collection::Tristate>(cmd.displayPref()));
97  collection.setIndexPref(static_cast<Collection::Tristate>(cmd.indexPref()));
98  const Protocol::CachePolicy &cp = cmd.cachePolicy();
99  collection.setCachePolicyCacheTimeout(cp.cacheTimeout());
100  collection.setCachePolicyCheckInterval(cp.checkInterval());
101  collection.setCachePolicyInherit(cp.inherit());
102  collection.setCachePolicyLocalParts(cp.localParts().join(QLatin1Char(' ')));
103  collection.setCachePolicySyncOnDemand(cp.syncOnDemand());
104 
105  DataStore *db = connection()->storageBackend();
106  Transaction transaction(db, QStringLiteral("CREATE"));
107 
108  QStringList effectiveMimeTypes = cmd.mimeTypes();
109  if (effectiveMimeTypes.isEmpty()) {
110  effectiveMimeTypes = parentContentTypes | Views::transform(&MimeType::name) | Actions::toQList;
111  }
112 
113  if (!db->appendCollection(collection, effectiveMimeTypes, cmd.attributes())) {
114  return failureResponse(QStringLiteral("Could not create collection %1, resourceId %2").arg(cmd.name()).arg(resourceId));
115  }
116 
117  if (!transaction.commit()) {
118  return failureResponse(QStringLiteral("Unable to commit transaction."));
119  }
120 
121  db->activeCachePolicy(collection);
122 
123  sendResponse<Protocol::FetchCollectionsResponse>(
124  HandlerHelper::fetchCollectionsResponse(akonadi(), collection));
125 
126  return successResponse<Protocol::CreateCollectionResponse>();
127 }
bool isValid() const
Returns whether the collection is valid.
Definition: collection.cpp:137
QString name() const
Returns the i18n&#39;ed name of the collection.
Definition: collection.cpp:225
The handler interfaces describes an entity capable of handling an AkonadiIMAP command.
Definition: handler.h:48
Represents a collection of PIM items.
Definition: collection.h:76
void setRemoteId(const QString &id)
Sets the remote id of the collection.
Definition: collection.cpp:117
void setName(const QString &name)
Sets the i18n&#39;ed name of the collection.
Definition: collection.cpp:237
void setEnabled(bool enabled)
Sets the collection&#39;s enabled state.
Definition: collection.cpp:374
QString fromUtf8(const char *str, int size)
Helper class for DataStore transaction handling.
Definition: transaction.h:37
void setRemoteRevision(const QString &revision)
Sets the remote revision of the collection.
Definition: collection.cpp:127
bool isEmpty() const const
virtual void activeCachePolicy(Collection &col)
Determines the active cache policy for this Collection.
Definition: datastore.cpp:1034
Id id() const
Returns the unique identifier of the collection.
Definition: collection.cpp:112
Helper integration between Akonadi and Qt.
CachePolicy cachePolicy() const
Returns the cache policy of the collection.
Definition: collection.cpp:353
This class handles all the database access.
Definition: datastore.h:108
QString mimeType(Type)
QObject * parent() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Jun 5 2020 23:08:54 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.