File indexing completed on 2024-11-10 04:40:53

0001 /*
0002     SPDX-FileCopyrightText: 2013, 2014 Daniel Vrátil <dvratil@redhat.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "searchrequest.h"
0008 
0009 #include "abstractsearchplugin.h"
0010 #include "akonadi.h"
0011 #include "akonadiserver_search_debug.h"
0012 #include "connection.h"
0013 #include "searchmanager.h"
0014 #include "searchtaskmanager.h"
0015 
0016 using namespace Akonadi::Server;
0017 
0018 SearchRequest::SearchRequest(const QByteArray &connectionId, SearchManager &searchManager, SearchTaskManager &agentSearchManager)
0019     : mConnectionId(connectionId)
0020     , mSearchManager(searchManager)
0021     , mAgentSearchManager(agentSearchManager)
0022 {
0023 }
0024 
0025 SearchRequest::~SearchRequest()
0026 {
0027 }
0028 
0029 QByteArray SearchRequest::connectionId() const
0030 {
0031     return mConnectionId;
0032 }
0033 
0034 void SearchRequest::setQuery(const QString &query)
0035 {
0036     mQuery = query;
0037 }
0038 
0039 QString SearchRequest::query() const
0040 {
0041     return mQuery;
0042 }
0043 
0044 void SearchRequest::setCollections(const QList<qint64> &collectionsIds)
0045 {
0046     mCollections = collectionsIds;
0047 }
0048 
0049 QList<qint64> SearchRequest::collections() const
0050 {
0051     return mCollections;
0052 }
0053 
0054 void SearchRequest::setMimeTypes(const QStringList &mimeTypes)
0055 {
0056     mMimeTypes = mimeTypes;
0057 }
0058 
0059 QStringList SearchRequest::mimeTypes() const
0060 {
0061     return mMimeTypes;
0062 }
0063 
0064 void SearchRequest::setRemoteSearch(bool remote)
0065 {
0066     mRemoteSearch = remote;
0067 }
0068 
0069 bool SearchRequest::remoteSearch() const
0070 {
0071     return mRemoteSearch;
0072 }
0073 
0074 void SearchRequest::setStoreResults(bool storeResults)
0075 {
0076     mStoreResults = storeResults;
0077 }
0078 
0079 QSet<qint64> SearchRequest::results() const
0080 {
0081     return mResults;
0082 }
0083 
0084 void SearchRequest::emitResults(const QSet<qint64> &results)
0085 {
0086     Q_EMIT resultsAvailable(results);
0087     if (mStoreResults) {
0088         mResults.unite(results);
0089     }
0090 }
0091 
0092 void SearchRequest::searchPlugins()
0093 {
0094     const QList<AbstractSearchPlugin *> plugins = mSearchManager.searchPlugins();
0095     for (AbstractSearchPlugin *plugin : plugins) {
0096         const QSet<qint64> result = plugin->search(mQuery, mCollections, mMimeTypes);
0097         emitResults(result);
0098     }
0099 }
0100 
0101 void SearchRequest::exec()
0102 {
0103     qCInfo(AKONADISERVER_SEARCH_LOG) << "Executing search" << mConnectionId;
0104 
0105     // TODO should we move this to the AgentSearchManager as well? If we keep it here the agents can be searched in parallel
0106     // since the plugin search is executed in this thread directly.
0107     searchPlugins();
0108 
0109     // If remote search is disabled, just finish here after searching the plugins
0110     if (!mRemoteSearch) {
0111         qCInfo(AKONADISERVER_SEARCH_LOG) << "Search " << mConnectionId << "done (without remote search)";
0112         return;
0113     }
0114 
0115     SearchTask task;
0116     task.id = mConnectionId;
0117     task.query = mQuery;
0118     task.mimeTypes = mMimeTypes;
0119     task.collections = mCollections;
0120     task.complete = false;
0121 
0122     mAgentSearchManager.addTask(&task);
0123 
0124     task.sharedLock.lock();
0125     for (;;) {
0126         if (task.complete) {
0127             break;
0128         }
0129 
0130         task.notifier.wait(&task.sharedLock);
0131 
0132         qCDebug(AKONADISERVER_SEARCH_LOG) << task.pendingResults.count() << "search results available in search" << task.id;
0133         if (!task.pendingResults.isEmpty()) {
0134             emitResults(task.pendingResults);
0135         }
0136         task.pendingResults.clear();
0137     }
0138 
0139     if (!task.pendingResults.isEmpty()) {
0140         emitResults(task.pendingResults);
0141     }
0142     task.sharedLock.unlock();
0143 
0144     qCInfo(AKONADISERVER_SEARCH_LOG) << "Search" << mConnectionId << "done (with remote search)";
0145 }
0146 
0147 #include "moc_searchrequest.cpp"