7#include "tagcreatehandler.h"
10#include "storage/countquerybuilder.h"
11#include "storage/datastore.h"
12#include "storage/querybuilder.h"
13#include "storage/transaction.h"
14#include "tagfetchhelper.h"
16#include "private/scope_p.h"
19using namespace Akonadi::Server;
21TagCreateHandler::TagCreateHandler(AkonadiServer &akonadi)
26bool TagCreateHandler::parseStream()
28 const auto &cmd = Protocol::cmdCast<Protocol::CreateTagCommand>(m_command);
30 if (!cmd.remoteId().isEmpty() && !connection()->context().resource().
isValid()) {
31 return failureResponse(QStringLiteral(
"Only resources can create tags with remote ID"));
34 Transaction trx(storageBackend(), QStringLiteral(
"TAGAPPEND"));
37 if (!cmd.type().isEmpty()) {
39 tagType = TagType::retrieveByNameOrCreate(typeName);
40 if (!tagType.isValid()) {
41 return failureResponse(QStringLiteral(
"Unable to create tagtype '") % typeName % QStringLiteral(
"'"));
48 QueryBuilder qb(Tag::tableName());
49 qb.addColumn(Tag::idColumn());
50 qb.addValueCondition(Tag::gidColumn(), Query::Equals, gid);
52 return failureResponse(
"Unable to list tags");
54 if (qb.query().next()) {
55 tagId = qb.query().value(0).toLongLong();
61 insertedTag.setGid(gid);
62 if (cmd.parentId() >= 0) {
63 insertedTag.setParentId(cmd.parentId());
65 if (tagType.isValid()) {
66 insertedTag.setTypeId(tagType.id());
68 if (!insertedTag.insert(&tagId)) {
69 return failureResponse(
"Failed to store tag");
72 const Protocol::Attributes attrs = cmd.attributes();
73 for (
auto iter = attrs.cbegin(), end = attrs.cend(); iter != end; ++iter) {
74 TagAttribute attribute;
75 attribute.setTagId(tagId);
76 attribute.setType(iter.key());
77 attribute.setValue(iter.value());
78 if (!attribute.insert()) {
79 return failureResponse(
"Failed to store tag attribute");
83 storageBackend()->notificationCollector()->tagAdded(insertedTag);
86 if (!cmd.remoteId().isEmpty()) {
87 const qint64 resourceId = connection()->context().resource().id();
89 CountQueryBuilder qb(TagRemoteIdResourceRelation::tableName());
90 qb.addValueCondition(TagRemoteIdResourceRelation::tagIdColumn(), Query::Equals, tagId);
91 qb.addValueCondition(TagRemoteIdResourceRelation::resourceIdColumn(), Query::Equals, resourceId);
93 return failureResponse(
"Failed to query for existing TagRemoteIdResourceRelation entries");
95 const bool exists = (qb.result() > 0);
101 QueryBuilder qb(TagRemoteIdResourceRelation::tableName(), QueryBuilder::Update);
102 qb.addValueCondition(TagRemoteIdResourceRelation::tagIdColumn(), Query::Equals, tagId);
103 qb.addValueCondition(TagRemoteIdResourceRelation::resourceIdColumn(), Query::Equals, resourceId);
104 qb.setColumnValue(TagRemoteIdResourceRelation::remoteIdColumn(),
QString::fromUtf8(cmd.remoteId()));
107 TagRemoteIdResourceRelation rel;
109 rel.setResourceId(resourceId);
114 return failureResponse(
"Failed to store tag remote ID");
120 Protocol::TagFetchScope fetchScope;
121 fetchScope.setFetchRemoteID(
true);
122 fetchScope.setFetchAllAttributes(
true);
124 TagFetchHelper helper(connection(),
Scope(tagId), fetchScope);
125 if (!helper.fetchTags()) {
126 return failureResponse(
"Failed to fetch the new tag");
129 return successResponse<Protocol::CreateTagResponse>();
The handler interfaces describes an entity capable of handling an AkonadiIMAP command.
Helper integration between Akonadi and Qt.
bool isValid(QStringView ifopt)
KOSM_EXPORT const char * typeName(Type type)
QString fromUtf8(QByteArrayView str)