Akonadi

searchhelper.cpp
1 /***************************************************************************
2  * SPDX-FileCopyrightText: 2006 Tobias Koenig <[email protected]> *
3  * SPDX-FileCopyrightText: 2014 Daniel Vr├ítil <[email protected]> *
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 
15 using namespace Akonadi::Server;
16 
17 static 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 
33 QVector<qint64> SearchHelper::matchSubcollectionsByMimeType(const QVector<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 QVector<qint64>();
56  }
57 
58  QMap<qint64 /* parentId */, QVector<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  QVector<qint64> results;
67  if (ancestors.contains(0)) {
68  for (const QVector<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 QVector<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 }
bool isEmpty() const const
void append(const T &value)
@ LeftJoin
NOTE: only supported for SELECT queries.
Definition: querybuilder.h:50
T value(int i) const const
bool contains(const T &value) const const
const Key key(const T &value, const Key &defaultKey) const const
Represents a WHERE condition tree.
Definition: query.h:61
Helper class to construct arbitrary SQL queries.
Definition: querybuilder.h:31
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Jul 2 2022 06:41:49 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.