File indexing completed on 2024-06-23 05:07:02

0001 /*
0002     SPDX-FileCopyrightText: 2014 Christian Mollekopf <mollekopf@kolabsys.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "relationremovehandler.h"
0008 
0009 #include "connection.h"
0010 #include "storage/datastore.h"
0011 #include "storage/querybuilder.h"
0012 #include "storage/queryhelper.h"
0013 #include "storage/selectquerybuilder.h"
0014 
0015 using namespace Akonadi;
0016 using namespace Akonadi::Server;
0017 
0018 RelationRemoveHandler::RelationRemoveHandler(AkonadiServer &akonadi)
0019     : Handler(akonadi)
0020 {
0021 }
0022 
0023 bool RelationRemoveHandler::parseStream()
0024 {
0025     const auto &cmd = Protocol::cmdCast<Protocol::RemoveRelationsCommand>(m_command);
0026 
0027     if (cmd.left() < 0 || cmd.right() < 0) {
0028         return failureResponse("Invalid relation id's provided");
0029     }
0030 
0031     RelationType relType;
0032     if (!cmd.type().isEmpty()) {
0033         relType = RelationType::retrieveByName(QString::fromUtf8(cmd.type()));
0034         if (!relType.isValid()) {
0035             return failureResponse("Failed to load relation type");
0036         }
0037     }
0038 
0039     SelectQueryBuilder<Relation> relationQuery;
0040     relationQuery.addValueCondition(Relation::leftIdFullColumnName(), Query::Equals, cmd.left());
0041     relationQuery.addValueCondition(Relation::rightIdFullColumnName(), Query::Equals, cmd.right());
0042     if (relType.isValid()) {
0043         relationQuery.addValueCondition(Relation::typeIdFullColumnName(), Query::Equals, relType.id());
0044     }
0045 
0046     if (!relationQuery.exec()) {
0047         return failureResponse("Failed to obtain relations");
0048     }
0049     const Relation::List relations = relationQuery.result();
0050     for (const Relation &relation : relations) {
0051         storageBackend()->notificationCollector()->relationRemoved(relation);
0052     }
0053 
0054     // Get all PIM items that are part of the relation
0055     SelectQueryBuilder<PimItem> itemsQuery;
0056     itemsQuery.setSubQueryMode(Query::Or);
0057     itemsQuery.addValueCondition(PimItem::idColumn(), Query::Equals, cmd.left());
0058     itemsQuery.addValueCondition(PimItem::idColumn(), Query::Equals, cmd.right());
0059 
0060     if (!itemsQuery.exec()) {
0061         throw failureResponse("Removing relation failed");
0062     }
0063     const PimItem::List items = itemsQuery.result();
0064     if (!items.isEmpty()) {
0065         storageBackend()->notificationCollector()->itemsRelationsChanged(items, Relation::List(), relations);
0066     }
0067 
0068     QueryBuilder qb(Relation::tableName(), QueryBuilder::Delete);
0069     qb.addValueCondition(Relation::leftIdFullColumnName(), Query::Equals, cmd.left());
0070     qb.addValueCondition(Relation::rightIdFullColumnName(), Query::Equals, cmd.right());
0071     if (relType.isValid()) {
0072         qb.addValueCondition(Relation::typeIdFullColumnName(), Query::Equals, relType.id());
0073     }
0074     if (!qb.exec()) {
0075         return failureResponse("Failed to remove relations");
0076     }
0077 
0078     return successResponse<Protocol::RemoveRelationsResponse>();
0079 }