Akonadi

collectionqueryhelper.cpp
1/*
2 SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "collectionqueryhelper.h"
8
9#include "handler.h"
10#include "storage/selectquerybuilder.h"
11
12using namespace Akonadi;
13using namespace Akonadi::Server;
14
15void CollectionQueryHelper::remoteIdToQuery(const QStringList &rids, const CommandContext &context, QueryBuilder &qb)
16{
17 if (rids.size() == 1) {
18 qb.addValueCondition(Collection::remoteIdFullColumnName(), Query::Equals, rids.first());
19 } else {
20 qb.addValueCondition(Collection::remoteIdFullColumnName(), Query::In, rids);
21 }
22
23 if (context.resource().isValid()) {
24 qb.addValueCondition(Collection::resourceIdFullColumnName(), Query::Equals, context.resource().id());
25 }
26}
27
28void CollectionQueryHelper::scopeToQuery(const Scope &scope, const CommandContext &context, QueryBuilder &qb)
29{
30 if (scope.scope() == Scope::Uid) {
31 if (!scope.isEmpty()) {
32 qb.addValueCondition(Collection::idFullColumnName(), Query::In, scope.uidSet());
33 }
34 } else if (scope.scope() == Scope::Rid) {
35 if (context.collectionId() <= 0 && !context.resource().isValid()) {
36 throw HandlerException("Operations based on remote identifiers require a resource or collection context");
37 }
38 CollectionQueryHelper::remoteIdToQuery(scope.ridSet(), context, qb);
39 } else if (scope.scope() == Scope::HierarchicalRid) {
40 if (!context.resource().isValid()) {
41 throw HandlerException("Operations based on hierarchical remote identifiers require a resource or collection context");
42 }
43 const Collection c = CollectionQueryHelper::resolveHierarchicalRID(scope.hridChain(), context.resource().id());
44 qb.addValueCondition(Collection::idFullColumnName(), Query::Equals, c.id());
45 } else {
46 throw HandlerException("WTF?");
47 }
48}
49
50bool CollectionQueryHelper::hasAllowedName(const Collection &collection, const QString &name, Collection::Id parent)
51{
52 Q_UNUSED(collection)
54 if (parent > 0) {
55 qb.addValueCondition(Collection::parentIdColumn(), Query::Equals, parent);
56 } else {
57 qb.addValueCondition(Collection::parentIdColumn(), Query::Is, QVariant());
58 }
59 qb.addValueCondition(Collection::nameColumn(), Query::Equals, name);
60 if (!qb.exec()) {
61 return false;
62 }
63 const QList<Collection> result = qb.result();
64 if (!result.isEmpty()) {
65 return result.first().id() == collection.id();
66 }
67 return true;
68}
69
70bool CollectionQueryHelper::canBeMovedTo(const Collection &collection, const Collection &_parent)
71{
72 if (_parent.isValid()) {
73 Collection parent = _parent;
74 for (;;) {
75 if (parent.id() == collection.id()) {
76 return false; // target is child of source
77 }
78 if (parent.parentId() == 0) {
79 break;
80 }
81 parent = parent.parent();
82 }
83 }
84 return hasAllowedName(collection, collection.name(), _parent.id());
85}
86
88{
89 if (ridChain.size() < 2) {
90 throw HandlerException("Empty or incomplete hierarchical RID chain");
91 }
92 if (!ridChain.last().isEmpty()) {
93 throw HandlerException("Hierarchical RID chain is not root-terminated");
94 }
95 Collection::Id parentId = 0;
96 Collection result;
97 for (int i = ridChain.size() - 2; i >= 0; --i) {
99 if (parentId > 0) {
100 qb.addValueCondition(Collection::parentIdColumn(), Query::Equals, parentId);
101 } else {
102 qb.addValueCondition(Collection::parentIdColumn(), Query::Is, QVariant());
103 }
104 qb.addValueCondition(Collection::remoteIdColumn(), Query::Equals, ridChain.at(i).remoteId);
105 qb.addValueCondition(Collection::resourceIdColumn(), Query::Equals, resId);
106 if (!qb.exec()) {
107 throw HandlerException("Unable to execute query");
108 }
109 const Collection::List results = qb.result();
110 const int resultSize = results.size();
111 if (resultSize == 0) {
112 throw HandlerException("Hierarchical RID does not specify an existing collection");
113 } else if (resultSize > 1) {
114 throw HandlerException("Hierarchical RID does not specify a unique collection");
115 }
116 result = results.first();
117 parentId = result.id();
118 }
119 return result;
120}
Represents a collection of PIM items.
Definition collection.h:62
qint64 Id
Describes the unique id type.
Definition collection.h:79
Helper class to construct arbitrary SQL queries.
void addValueCondition(const QString &column, Query::CompareOperator op, const QVariant &value, ConditionType type=WhereCondition)
Add a WHERE or HAVING condition which compares a column with a given value.
bool exec()
Executes the query, returns true on success.
Helper class for creating and executing database SELECT queries.
QList< T > result()
Returns the result of this SELECT query.
void remoteIdToQuery(const QStringList &rids, const CommandContext &context, QueryBuilder &qb)
Add conditions to qb for the given remote identifier rid.
bool hasAllowedName(const Collection &collection, const QString &name, Collection::Id parent)
Checks if a collection could exist in the given parent folder with the given name.
void scopeToQuery(const Scope &scope, const CommandContext &context, QueryBuilder &qb)
Add conditions to qb for the given collection operation scope scope.
Collection resolveHierarchicalRID(const QList< Scope::HRID > &hridChain, Resource::Id resId)
Retrieve the collection referred to by the given hierarchical RID chain.
bool canBeMovedTo(const Collection &collection, const Collection &parent)
Checks if a collection could be moved from its current parent into the given one.
Helper integration between Akonadi and Qt.
const_reference at(qsizetype i) const const
T & first()
bool isEmpty() const const
T & last()
qsizetype size() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:13:38 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.