Akonadi

searchhelper.cpp
1/***************************************************************************
2 * SPDX-FileCopyrightText: 2006 Tobias Koenig <tokoe@kde.org> *
3 * SPDX-FileCopyrightText: 2014 Daniel Vrátil <dvratil@redhat.com> *
4 * *
5 * SPDX-License-Identifier: LGPL-2.0-or-later *
6 ***************************************************************************/
7
8#include "searchhelper.h"
9
10#include "entities.h"
11#include "storage/countquerybuilder.h"
12
13#include "private/protocol_p.h"
14
15using namespace Akonadi::Server;
16
17static qint64 parentCollectionId(qint64 collectionId)
18{
19 QueryBuilder qb(Collection::tableName(), QueryBuilder::Select);
20 qb.addColumn(Collection::parentIdColumn());
21 qb.addValueCondition(Collection::idColumn(), Query::Equals, collectionId);
22 if (!qb.exec()) {
23 return -1;
24 }
25 if (!qb.query().next()) {
26 return -1;
27 }
28 const auto parentId = qb.query().value(0).toLongLong();
29 qb.query().finish();
30 return parentId;
31}
32
33QList<qint64> SearchHelper::matchSubcollectionsByMimeType(const QList<qint64> &ancestors, const QStringList &mimeTypes)
34{
35 // Get all collections with given mime types
36 QueryBuilder qb(Collection::tableName(), QueryBuilder::Select);
37 qb.setDistinct(true);
38 qb.addColumn(Collection::idFullColumnName());
39 qb.addColumn(Collection::parentIdFullColumnName());
40 qb.addJoin(QueryBuilder::LeftJoin,
41 CollectionMimeTypeRelation::tableName(),
42 CollectionMimeTypeRelation::leftFullColumnName(),
43 Collection::idFullColumnName());
44 qb.addJoin(QueryBuilder::LeftJoin, MimeType::tableName(), CollectionMimeTypeRelation::rightFullColumnName(), MimeType::idFullColumnName());
45 Query::Condition cond(Query::Or);
46 for (const QString &mt : mimeTypes) {
47 cond.addValueCondition(MimeType::nameFullColumnName(), Query::Equals, mt);
48 }
49 if (!cond.isEmpty()) {
50 qb.addCondition(cond);
51 }
52
53 if (!qb.exec()) {
54 qCWarning(AKONADISERVER_LOG) << "Failed to query search collections";
55 return QList<qint64>();
56 }
57
58 QMap<qint64 /* parentId */, QList<qint64> /* collectionIds */> candidateCollections;
59 while (qb.query().next()) {
60 candidateCollections[qb.query().value(1).toLongLong()].append(qb.query().value(0).toLongLong());
61 }
62 qb.query().finish();
63
64 // If the ancestors list contains root, then return what we got, since everything
65 // is sub collection of root
66 QList<qint64> results;
67 if (ancestors.contains(0)) {
68 for (const QList<qint64> &res : std::as_const(candidateCollections)) {
69 results += res;
70 }
71 return results;
72 }
73
74 // Try to resolve direct descendants
75 for (qint64 ancestor : ancestors) {
76 const QList<qint64> cols = candidateCollections.take(ancestor);
77 if (!cols.isEmpty()) {
78 results += cols;
79 }
80 }
81
82 for (auto iter = candidateCollections.begin(), iterEnd = candidateCollections.end(); iter != iterEnd; ++iter) {
83 // Traverse the collection chain up to root
84 qint64 parentId = iter.key();
85 while (!ancestors.contains(parentId) && parentId > 0) {
86 parentId = parentCollectionId(parentId);
87 }
88 // Ok, we found a requested ancestor in the parent chain
89 if (parentId > 0) {
90 results += iter.value();
91 }
92 }
93
94 return results;
95}
Helper class to construct arbitrary SQL queries.
@ LeftJoin
NOTE: only supported for SELECT queries.
Represents a WHERE condition tree.
Definition query.h:62
A glue between Qt and the standard library.
void append(QList< T > &&value)
bool contains(const AT &value) const const
bool isEmpty() const const
T value(qsizetype i) 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.