7#include "tagmodifyhandler.h"
10#include "shared/akranges.h"
11#include "storage/datastore.h"
12#include "storage/querybuilder.h"
13#include "tagfetchhelper.h"
16using namespace Akonadi::Server;
17using namespace AkRanges;
19TagModifyHandler::TagModifyHandler(AkonadiServer &akonadi)
24bool TagModifyHandler::parseStream()
26 const auto &cmd = Protocol::cmdCast<Protocol::ModifyTagCommand>(m_command);
28 Tag changedTag = Tag::retrieveById(cmd.tagId());
29 if (!changedTag.isValid()) {
30 return failureResponse(
"No such tag");
36 const TagAttribute::List attributes = TagAttribute::retrieveFiltered(TagAttribute::tagIdFullColumnName(), cmd.tagId());
37 const auto attributesMap = attributes | Views::transform([](
const auto &attr) {
38 return std::make_pair(attr.type(), attr);
42 if (cmd.modifiedParts() & Protocol::ModifyTagCommand::ParentId) {
43 if (cmd.parentId() != changedTag.parentId()) {
44 changedTag.setParentId(cmd.parentId());
45 changes << AKONADI_PARAM_PARENT;
49 if (cmd.modifiedParts() & Protocol::ModifyTagCommand::Type) {
50 TagType
type = TagType::retrieveById(changedTag.typeId());
52 if (newTypeName !=
type.name()) {
53 const TagType newType = TagType::retrieveByNameOrCreate(newTypeName);
54 if (!newType.isValid()) {
55 return failureResponse(
"Failed to create new tag type");
57 changedTag.setTagType(newType);
58 changes << AKONADI_PARAM_MIMETYPE;
62 bool tagRemoved =
false;
63 if (cmd.modifiedParts() & Protocol::ModifyTagCommand::RemoteId) {
64 if (!connection()->context().resource().
isValid()) {
65 return failureResponse(
"Only resources can change tag remote ID");
69 QueryBuilder qb(TagRemoteIdResourceRelation::tableName(), QueryBuilder::Delete);
70 qb.addValueCondition(TagRemoteIdResourceRelation::tagIdColumn(), Query::Equals, cmd.tagId());
71 qb.addValueCondition(TagRemoteIdResourceRelation::resourceIdColumn(), Query::Equals, connection()->context().resource().
id());
74 if (!cmd.remoteId().isEmpty()) {
75 TagRemoteIdResourceRelation remoteIdRelation;
77 remoteIdRelation.setResourceId(connection()->context().resource().
id());
78 remoteIdRelation.setTag(changedTag);
79 if (!remoteIdRelation.insert()) {
80 return failureResponse(
"Failed to insert remotedid resource relation");
83 const int tagRidsCount = TagRemoteIdResourceRelation::count(TagRemoteIdResourceRelation::tagIdColumn(), changedTag.
id());
87 if (tagRidsCount == 0) {
88 if (!storageBackend()->removeTags(
Tag::List() << changedTag)) {
89 return failureResponse(
"Failed to remove tag");
98 if (cmd.modifiedParts() & Protocol::ModifyTagCommand::RemovedAttributes) {
99 const auto attrNames = cmd.removedAttributes();
100 for (
const QByteArray &attrName : attrNames) {
102 TagAttribute::remove(attribute.id());
107 if (cmd.modifiedParts() & Protocol::ModifyTagCommand::Attributes) {
109 for (
auto iter = attrs.
cbegin(), end = attrs.
cend(); iter != end; ++iter) {
110 if (attributesMap.contains(iter.key())) {
111 TagAttribute attribute = attributesMap.value(iter.key());
112 attribute.setValue(iter.value());
113 if (!attribute.update()) {
114 return failureResponse(
"Failed to update attribute");
118 attribute.setTagId(cmd.tagId());
119 attribute.setType(iter.key());
120 attribute.setValue(iter.value());
121 if (!attribute.insert()) {
122 return failureResponse(
"Failed to insert attribute");
125 changes << iter.key();
130 if (!changedTag.update()) {
131 return failureResponse(
"Failed to store changes");
137 Protocol::TagFetchScope fetchScope;
138 fetchScope.setFetchRemoteID(
true);
139 fetchScope.setFetchAllAttributes(
true);
141 TagFetchHelper helper(connection(), Scope(cmd.tagId()), fetchScope);
142 if (!helper.fetchTags()) {
143 return failureResponse(
"Failed to fetch response");
146 successResponse<Protocol::DeleteTagResponse>();
149 return successResponse<Protocol::ModifyTagResponse>();
NotificationCollector * notificationCollector()
Returns the notification collector of this DataStore object.
The handler interfaces describes an entity capable of handling an AkonadiIMAP command.
void tagChanged(const Tag &tag)
Notify about a changed tag.
Helper class to construct arbitrary SQL queries.
Attribute that stores the properties that are used to display a tag.
Id id() const
Returns the unique identifier of the tag.
Helper integration between Akonadi and Qt.
bool isValid(QStringView ifopt)
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
const_iterator cbegin() const const
const_iterator cend() const const
bool isEmpty() const const
QString fromUtf8(QByteArrayView str)