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"