File indexing completed on 2024-06-23 05:07:00
0001 /*************************************************************************** 0002 * SPDX-FileCopyrightText: 2006 Ingo Kloecker <kloecker@kde.org> * 0003 * * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later * 0005 ***************************************************************************/ 0006 #include "collectioncreatehandler.h" 0007 0008 #include "connection.h" 0009 #include "handlerhelper.h" 0010 #include "shared/akranges.h" 0011 #include "storage/datastore.h" 0012 #include "storage/selectquerybuilder.h" 0013 #include "storage/transaction.h" 0014 0015 #include "private/scope_p.h" 0016 0017 using namespace Akonadi; 0018 using namespace Akonadi::Server; 0019 using namespace AkRanges; 0020 0021 CollectionCreateHandler::CollectionCreateHandler(AkonadiServer &akonadi) 0022 : Handler(akonadi) 0023 { 0024 } 0025 0026 bool CollectionCreateHandler::parseStream() 0027 { 0028 const auto &cmd = Protocol::cmdCast<Protocol::CreateCollectionCommand>(m_command); 0029 0030 if (cmd.name().isEmpty()) { 0031 return failureResponse(QStringLiteral("Invalid collection name")); 0032 } 0033 0034 Collection parent; 0035 qint64 resourceId = 0; 0036 bool forceVirtual = false; 0037 MimeType::List parentContentTypes; 0038 0039 // Invalid or empty scope means we refer to root collection 0040 if (cmd.parent().scope() != Scope::Invalid && !cmd.parent().isEmpty()) { 0041 parent = HandlerHelper::collectionFromScope(cmd.parent(), connection()->context()); 0042 if (!parent.isValid()) { 0043 return failureResponse(QStringLiteral("Invalid parent collection")); 0044 } 0045 0046 // check if parent can contain a sub-folder 0047 parentContentTypes = parent.mimeTypes(); 0048 const auto hasMimeType = [](const QString &mimeType) { 0049 return [mimeType](const MimeType &mt) { 0050 return mt.name() == mimeType; 0051 }; 0052 }; 0053 const bool canContainCollections = parentContentTypes | Actions::any(hasMimeType(CollectionMimeType)); 0054 const bool canContainVirtualCollections = parentContentTypes | Actions::any(hasMimeType(VirtualCollectionMimeType)); 0055 0056 if (!canContainCollections && !canContainVirtualCollections) { 0057 return failureResponse(QStringLiteral("Parent collection can not contain sub-collections")); 0058 } 0059 0060 // If only virtual collections are supported, force every new collection to 0061 // be virtual. Otherwise depend on VIRTUAL attribute in the command 0062 if (canContainVirtualCollections && !canContainCollections) { 0063 forceVirtual = true; 0064 } 0065 0066 // inherit resource 0067 resourceId = parent.resourceId(); 0068 } else { 0069 const QString sessionId = QString::fromUtf8(connection()->sessionId()); 0070 Resource res = Resource::retrieveByName(sessionId); 0071 if (!res.isValid()) { 0072 return failureResponse(QStringLiteral("Cannot create top-level collection")); 0073 } 0074 resourceId = res.id(); 0075 } 0076 0077 Collection collection; 0078 if (parent.isValid()) { 0079 collection.setParentId(parent.id()); 0080 } 0081 collection.setName(cmd.name()); 0082 collection.setResourceId(resourceId); 0083 collection.setRemoteId(cmd.remoteId()); 0084 collection.setRemoteRevision(cmd.remoteRevision()); 0085 collection.setIsVirtual(cmd.isVirtual() || forceVirtual); 0086 collection.setEnabled(cmd.enabled()); 0087 collection.setSyncPref(static_cast<Collection::Tristate>(cmd.syncPref())); 0088 collection.setDisplayPref(static_cast<Collection::Tristate>(cmd.displayPref())); 0089 collection.setIndexPref(static_cast<Collection::Tristate>(cmd.indexPref())); 0090 const Protocol::CachePolicy &cp = cmd.cachePolicy(); 0091 collection.setCachePolicyCacheTimeout(cp.cacheTimeout()); 0092 collection.setCachePolicyCheckInterval(cp.checkInterval()); 0093 collection.setCachePolicyInherit(cp.inherit()); 0094 collection.setCachePolicyLocalParts(cp.localParts().join(QLatin1Char(' '))); 0095 collection.setCachePolicySyncOnDemand(cp.syncOnDemand()); 0096 0097 DataStore *db = connection()->storageBackend(); 0098 Transaction transaction(db, QStringLiteral("CREATE")); 0099 0100 QStringList effectiveMimeTypes = cmd.mimeTypes(); 0101 if (effectiveMimeTypes.isEmpty()) { 0102 effectiveMimeTypes = parentContentTypes | Views::transform(&MimeType::name) | Actions::toQList; 0103 } 0104 0105 if (!db->appendCollection(collection, effectiveMimeTypes, cmd.attributes())) { 0106 return failureResponse(QStringLiteral("Could not create collection %1, resourceId %2").arg(cmd.name()).arg(resourceId)); 0107 } 0108 0109 if (!transaction.commit()) { 0110 return failureResponse(QStringLiteral("Unable to commit transaction.")); 0111 } 0112 0113 db->activeCachePolicy(collection); 0114 0115 sendResponse<Protocol::FetchCollectionsResponse>(HandlerHelper::fetchCollectionsResponse(akonadi(), collection)); 0116 0117 return successResponse<Protocol::CreateCollectionResponse>(); 0118 }