Akonadi

itemqueryhelper.cpp
1 /*
2  Copyright (c) 2009 Volker Krause <[email protected]>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #include "itemqueryhelper.h"
21 
22 #include "commandcontext.h"
23 #include "entities.h"
24 #include "storage/querybuilder.h"
25 #include "handler.h"
26 #include "storage/queryhelper.h"
27 #include "collectionqueryhelper.h"
28 
29 #include <private/scope_p.h>
30 #include <private/imapset_p.h>
31 
32 using namespace Akonadi;
33 using namespace Akonadi::Server;
34 
35 void ItemQueryHelper::itemSetToQuery(const ImapSet &set, QueryBuilder &qb, const Collection &collection)
36 {
37  if (!set.isEmpty()) {
38  QueryHelper::setToQuery(set, PimItem::idFullColumnName(), qb);
39  }
40  if (collection.isValid()) {
41  if (collection.isVirtual() || collection.resource().isVirtual()) {
42  qb.addJoin(QueryBuilder::InnerJoin, CollectionPimItemRelation::tableName(),
43  CollectionPimItemRelation::rightFullColumnName(), PimItem::idFullColumnName());
44  qb.addValueCondition(CollectionPimItemRelation::leftFullColumnName(), Query::Equals, collection.id());
45  } else {
46  qb.addValueCondition(PimItem::collectionIdFullColumnName(), Query::Equals, collection.id());
47  }
48  }
49 }
50 
51 void ItemQueryHelper::itemSetToQuery(const ImapSet &set, const CommandContext &context, QueryBuilder &qb)
52 {
53  if (context.collectionId() >= 0) {
54  itemSetToQuery(set, qb, context.collection());
55  } else {
56  itemSetToQuery(set, qb);
57  }
58 
59  const auto tagId = context.tagId();
60  if (tagId.has_value()) {
61  //When querying for items by tag, only return matches from that resource
62  if (context.resource().isValid()) {
64  PimItem::collectionIdFullColumnName(), Collection::idFullColumnName());
65  qb.addValueCondition(Collection::resourceIdFullColumnName(), Query::Equals, context.resource().id());
66  }
67  qb.addJoin(QueryBuilder::InnerJoin, PimItemTagRelation::tableName(),
68  PimItem::idFullColumnName(), PimItemTagRelation::leftFullColumnName());
69  qb.addValueCondition(PimItemTagRelation::rightFullColumnName(), Query::Equals, tagId.value());
70  }
71 }
72 
73 void ItemQueryHelper::remoteIdToQuery(const QStringList &rids, const CommandContext &context, QueryBuilder &qb)
74 {
75  if (rids.size() == 1) {
76  qb.addValueCondition(PimItem::remoteIdFullColumnName(), Query::Equals, rids.first());
77  } else {
78  qb.addValueCondition(PimItem::remoteIdFullColumnName(), Query::In, rids);
79  }
80 
81  if (context.resource().isValid()) {
83  PimItem::collectionIdFullColumnName(), Collection::idFullColumnName());
84  qb.addValueCondition(Collection::resourceIdFullColumnName(), Query::Equals, context.resource().id());
85  }
86  if (context.collectionId() > 0) {
87  qb.addValueCondition(PimItem::collectionIdFullColumnName(), Query::Equals, context.collectionId());
88  }
89 
90  const auto tagId = context.tagId();
91  if (tagId.has_value()) {
92  qb.addJoin(QueryBuilder::InnerJoin, PimItemTagRelation::tableName(),
93  PimItem::idFullColumnName(), PimItemTagRelation::leftFullColumnName());
94  qb.addValueCondition(PimItemTagRelation::rightFullColumnName(), Query::Equals, tagId.value());
95  }
96 }
97 
98 void ItemQueryHelper::gidToQuery(const QStringList &gids, const CommandContext &context, QueryBuilder &qb)
99 {
100  if (gids.size() == 1) {
101  qb.addValueCondition(PimItem::gidFullColumnName(), Query::Equals, gids.first());
102  } else {
103  qb.addValueCondition(PimItem::gidFullColumnName(), Query::In, gids);
104  }
105 
106  const auto tagId = context.tagId();
107  if (tagId.has_value()) {
108  //When querying for items by tag, only return matches from that resource
109  if (context.resource().isValid()) {
111  PimItem::collectionIdFullColumnName(), Collection::idFullColumnName());
112  qb.addValueCondition(Collection::resourceIdFullColumnName(), Query::Equals, context.resource().id());
113  }
114  qb.addJoin(QueryBuilder::InnerJoin, PimItemTagRelation::tableName(),
115  PimItem::idFullColumnName(), PimItemTagRelation::leftFullColumnName());
116  qb.addValueCondition(PimItemTagRelation::rightFullColumnName(), Query::Equals, tagId.value());
117  }
118 }
119 
120 void ItemQueryHelper::scopeToQuery(const Scope &scope, const CommandContext &context, QueryBuilder &qb)
121 {
122  // Handle fetch by collection/tag
123  if (scope.scope() == Scope::Invalid && !context.isEmpty()) {
124  itemSetToQuery(ImapSet(), context, qb);
125  return;
126  }
127 
128  if (scope.scope() == Scope::Uid) {
129  itemSetToQuery(scope.uidSet(), context, qb);
130  return;
131  }
132 
133  if (scope.scope() == Scope::Gid) {
134  ItemQueryHelper::gidToQuery(scope.gidSet(), context, qb);
135  return;
136  }
137 
138  if (context.collectionId() <= 0 && !context.resource().isValid()) {
139  throw HandlerException("Operations based on remote identifiers require a resource or collection context");
140  }
141 
142  if (scope.scope() == Scope::Rid) {
143  ItemQueryHelper::remoteIdToQuery(scope.ridSet(), context, qb);
144  return;
145  } else if (scope.scope() == Scope::HierarchicalRid) {
146  QVector<Scope::HRID> hridChain = scope.hridChain();
147  const Scope::HRID itemHRID = hridChain.takeFirst();
148  const Collection parentCol = CollectionQueryHelper::resolveHierarchicalRID(hridChain, context.resource().id());
149  const Collection oldSelection = context.collection();
150  CommandContext tmpContext(context);
151  tmpContext.setCollection(parentCol);
152  remoteIdToQuery(QStringList() << itemHRID.remoteId, tmpContext, qb);
153  return;
154  }
155 
156  throw HandlerException("Dude, WTF?!?");
157 }
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.
Resource resource() const
Retrieve the Resource record referred to by the resourceId column of this record. ...
void itemSetToQuery(const ImapSet &set, QueryBuilder &qb, const Collection &collection=Collection())
Add conditions to qb for the given item set set.
NOTE: only supported for UPDATE and SELECT queries.
Definition: querybuilder.h:62
void addJoin(JoinType joinType, const QString &table, const Query::Condition &condition)
Join a table to the query.
Collection resolveHierarchicalRID(const QVector< Scope::HRID > &hridChain, Resource::Id resId)
Retrieve the collection referred to by the given hierarchical RID chain.
int size() const const
bool isVirtual() const
Returns the value of the isVirtual column of this record.
Definition: entities.cpp:558
T & first()
static QString tableName()
Returns the name of the SQL table.
Definition: entities.cpp:1640
void setToQuery(const ImapSet &set, const QString &column, QueryBuilder &qb)
Add conditions to qb for the given uid set set applied to column.
Definition: queryhelper.cpp:29
T takeFirst()
Helper integration between Akonadi and Qt.
void remoteIdToQuery(const QStringList &rids, const CommandContext &context, QueryBuilder &qb)
Add conditions to qb for the given remote identifier rid.
bool isVirtual() const
Returns the value of the isVirtual column of this record.
void scopeToQuery(const Scope &scope, const CommandContext &context, QueryBuilder &qb)
Add conditions to qb for the given item operation scope scope.
Helper class to construct arbitrary SQL queries.
Definition: querybuilder.h:45
Representation of a record in the Collection table.
Definition: entities.h:451
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sun May 24 2020 22:46:16 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.