File indexing completed on 2024-06-23 05:07:03

0001 /*
0002  * SPDX-FileCopyrightText: 2013 Daniel Vrátil <dvratil@redhat.com>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-or-later
0005  *
0006  */
0007 
0008 #include "searchresulthandler.h"
0009 
0010 #include "akonadi.h"
0011 #include "connection.h"
0012 #include "search/searchtaskmanager.h"
0013 #include "storage/itemqueryhelper.h"
0014 #include "storage/querybuilder.h"
0015 
0016 #include "private/imapset_p.h"
0017 #include "private/scope_p.h"
0018 
0019 using namespace Akonadi;
0020 using namespace Akonadi::Server;
0021 
0022 SearchResultHandler::SearchResultHandler(AkonadiServer &akonadi)
0023     : Handler(akonadi)
0024 {
0025 }
0026 
0027 bool SearchResultHandler::parseStream()
0028 {
0029     const auto &cmd = Protocol::cmdCast<Protocol::SearchResultCommand>(m_command);
0030 
0031     if (!checkScopeConstraints(cmd.result(), Scope::Uid | Scope::Rid)) {
0032         return fail(cmd.searchId(), QStringLiteral("Only UID or RID scopes are allowed in SEARECH_RESULT"));
0033     }
0034 
0035     QSet<qint64> ids;
0036     if (cmd.result().scope() == Scope::Rid && !cmd.result().isEmpty()) {
0037         QueryBuilder qb(PimItem::tableName());
0038         qb.addColumn(PimItem::idFullColumnName());
0039         ItemQueryHelper::remoteIdToQuery(cmd.result().ridSet(), connection()->context(), qb);
0040         qb.addValueCondition(PimItem::collectionIdFullColumnName(), Query::Equals, cmd.collectionId());
0041 
0042         if (!qb.exec()) {
0043             return fail(cmd.searchId(), QStringLiteral("Failed to convert RID to UID"));
0044         }
0045 
0046         QSqlQuery query = qb.query();
0047         while (query.next()) {
0048             ids << query.value(0).toLongLong();
0049         }
0050         query.finish();
0051     } else if (cmd.result().scope() == Scope::Uid && !cmd.result().isEmpty()) {
0052         const ImapSet result = cmd.result().uidSet();
0053         const ImapInterval::List lstInterval = result.intervals();
0054         for (const ImapInterval &interval : lstInterval) {
0055             for (qint64 i = interval.begin(), end = interval.end(); i <= end; ++i) {
0056                 ids.insert(i);
0057             }
0058         }
0059     }
0060     akonadi().agentSearchManager().pushResults(cmd.searchId(), ids, connection());
0061 
0062     return successResponse<Protocol::SearchResultResponse>();
0063 }
0064 
0065 bool SearchResultHandler::fail(const QByteArray &searchId, const QString &error)
0066 {
0067     akonadi().agentSearchManager().pushResults(searchId, QSet<qint64>(), connection());
0068     return failureResponse(error);
0069 }