Akonadi

itemqueryhelper.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 "itemqueryhelper.h"
8
9#include "collectionqueryhelper.h"
10#include "commandcontext.h"
11#include "handler.h"
12#include "storage/querybuilder.h"
13
14#include "private/scope_p.h"
15
16using namespace Akonadi;
17using namespace Akonadi::Server;
18
20{
21 if (!set.isEmpty()) {
22 qb.addValueCondition(PimItem::idFullColumnName(), Query::In, set);
23 }
24 if (collection.isValid()) {
25 if (collection.isVirtual() || collection.resource().isVirtual()) {
27 CollectionPimItemRelation::tableName(),
28 CollectionPimItemRelation::rightFullColumnName(),
29 qb.getTableWithColumn(PimItem::idColumn()));
30 qb.addValueCondition(CollectionPimItemRelation::leftFullColumnName(), Query::Equals, collection.id());
31 } else {
32 qb.addValueCondition(qb.getTableWithColumn(PimItem::collectionIdColumn()), Query::Equals, collection.id());
33 }
34 }
35}
36
37void ItemQueryHelper::itemSetToQuery(const QList<PimItem::Id> &set, const CommandContext &context, QueryBuilder &qb)
38{
39 if (context.collectionId() >= 0) {
40 itemSetToQuery(set, qb, context.collection());
41 } else {
42 itemSetToQuery(set, qb);
43 }
44
45 const auto tagId = context.tagId();
46 if (tagId.has_value()) {
47 // When querying for items by tag, only return matches from that resource
48 if (context.resource().isValid()) {
49 qb.addJoin(QueryBuilder::InnerJoin, Collection::tableName(), qb.getTableWithColumn(PimItem::collectionIdColumn()), Collection::idFullColumnName());
50 qb.addValueCondition(Collection::resourceIdFullColumnName(), Query::Equals, context.resource().id());
51 }
53 PimItemTagRelation::tableName(),
54 qb.getTableWithColumn(PimItem::idColumn()),
55 PimItemTagRelation::leftFullColumnName());
56 qb.addValueCondition(PimItemTagRelation::rightFullColumnName(), Query::Equals, *tagId);
57 }
58}
59
60void ItemQueryHelper::remoteIdToQuery(const QStringList &rids, const CommandContext &context, QueryBuilder &qb)
61{
62 if (rids.size() == 1) {
63 qb.addValueCondition(qb.getTableWithColumn(PimItem::remoteIdColumn()), Query::Equals, rids.first());
64 } else {
65 qb.addValueCondition(qb.getTableWithColumn(PimItem::remoteIdColumn()), Query::In, rids);
66 }
67
68 if (context.resource().isValid()) {
69 qb.addJoin(QueryBuilder::InnerJoin, Collection::tableName(), qb.getTableWithColumn(PimItem::collectionIdColumn()), Collection::idFullColumnName());
70 qb.addValueCondition(Collection::resourceIdFullColumnName(), Query::Equals, context.resource().id());
71 }
72 if (context.collectionId() > 0) {
73 qb.addValueCondition(qb.getTableWithColumn(PimItem::collectionIdColumn()), Query::Equals, context.collectionId());
74 }
75
76 const auto tagId = context.tagId();
77 if (tagId.has_value()) {
79 PimItemTagRelation::tableName(),
80 qb.getTableWithColumn(PimItem::idColumn()),
81 PimItemTagRelation::leftFullColumnName());
82 qb.addValueCondition(PimItemTagRelation::rightFullColumnName(), Query::Equals, *tagId);
83 }
84}
85
86void ItemQueryHelper::gidToQuery(const QStringList &gids, const CommandContext &context, QueryBuilder &qb)
87{
88 if (gids.size() == 1) {
89 qb.addValueCondition(qb.getTableWithColumn(PimItem::gidColumn()), Query::Equals, gids.first());
90 } else {
91 qb.addValueCondition(qb.getTableWithColumn(PimItem::gidColumn()), Query::In, gids);
92 }
93
94 const auto tagId = context.tagId();
95 if (tagId.has_value()) {
96 // When querying for items by tag, only return matches from that resource
97 if (context.resource().isValid()) {
98 qb.addJoin(QueryBuilder::InnerJoin, Collection::tableName(), qb.getTableWithColumn(PimItem::collectionIdColumn()), Collection::idFullColumnName());
99 qb.addValueCondition(Collection::resourceIdFullColumnName(), Query::Equals, context.resource().id());
100 }
102 PimItemTagRelation::tableName(),
103 qb.getTableWithColumn(PimItem::idColumn()),
104 PimItemTagRelation::leftFullColumnName());
105 qb.addValueCondition(PimItemTagRelation::rightFullColumnName(), Query::Equals, *tagId);
106 }
107}
108
109void ItemQueryHelper::scopeToQuery(const Scope &scope, const CommandContext &context, QueryBuilder &qb)
110{
111 // Handle fetch by collection/tag
112 if (scope.scope() == Scope::Invalid && !context.isEmpty()) {
113 itemSetToQuery({}, context, qb);
114 return;
115 }
116
117 if (scope.scope() == Scope::Uid) {
118 itemSetToQuery(scope.uidSet(), context, qb);
119 return;
120 }
121
122 if (scope.scope() == Scope::Gid) {
123 ItemQueryHelper::gidToQuery(scope.gidSet(), context, qb);
124 return;
125 }
126
127 if (context.collectionId() <= 0 && !context.resource().isValid()) {
128 throw HandlerException("Operations based on remote identifiers require a resource or collection context");
129 }
130
131 if (scope.scope() == Scope::Rid) {
132 ItemQueryHelper::remoteIdToQuery(scope.ridSet(), context, qb);
133 return;
134 } else if (scope.scope() == Scope::HierarchicalRid) {
135 QList<Scope::HRID> hridChain = scope.hridChain();
136 const Scope::HRID itemHRID = hridChain.takeFirst();
137 const Collection parentCol = CollectionQueryHelper::resolveHierarchicalRID(hridChain, context.resource().id());
138 const Collection oldSelection = context.collection();
139 CommandContext tmpContext(context);
140 tmpContext.setCollection(parentCol);
141 remoteIdToQuery(QStringList() << itemHRID.remoteId, tmpContext, qb);
142 return;
143 }
144
145 throw HandlerException("Dude, WTF?!?");
146}
Represents a collection of PIM items.
Definition collection.h:62
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.
QString getTableWithColumn(const QString &column) const
Returns concatenated table name with column name.
void addJoin(JoinType joinType, const QString &table, const Query::Condition &condition)
Join a table to the query.
@ InnerJoin
NOTE: only supported for UPDATE and SELECT queries.
Collection resolveHierarchicalRID(const QList< Scope::HRID > &hridChain, Resource::Id resId)
Retrieve the collection referred to by the given hierarchical RID chain.
void remoteIdToQuery(const QStringList &rids, const CommandContext &context, QueryBuilder &qb)
Add conditions to qb for the given remote identifier rid.
void scopeToQuery(const Scope &scope, const CommandContext &context, QueryBuilder &qb)
Add conditions to qb for the given item operation scope scope.
void itemSetToQuery(const QList< PimItem::Id > &set, QueryBuilder &qb, const Collection &collection=Collection())
Add conditions to qb for the given item set set.
Helper integration between Akonadi and Qt.
T & first()
bool isEmpty() const const
qsizetype size() const const
value_type takeFirst()
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.