repoindex/alpm/suggestionslookup.cpp

82 lines
2.6 KiB
C++

#include "./suggestionslookup.h"
#include "./manager.h"
#include "./repository.h"
#include <QJsonObject>
#include <QJsonArray>
#include <assert.h>
namespace RepoIndex {
SuggestionsLookup::SuggestionsLookup(Manager &manager, const QJsonObject &request, QObject *parent) :
PackageLookup(parent),
m_searchTerm(request.value(QStringLiteral("term")).toString())
{
m_id = request.value(QStringLiteral("id"));
if(m_searchTerm.isEmpty()) {
m_errors << QStringLiteral("No search term specified.");
}
const auto repos = request.value(QStringLiteral("repos")).toArray();
if(repos.isEmpty()) {
m_errors << QStringLiteral("No repositories specified.");
}
if(m_errors.isEmpty()) {
m_repos.reserve(repos.size());
for(const auto &repoName : repos) {
if(auto *repo = manager.repositoryByName(repoName.toString())) {
m_repos << repo;
} else {
m_errors << QStringLiteral("The specified repository \"%1\" does not exist.").arg(repoName.toString());
}
}
return;
}
deleteLater();
}
void SuggestionsLookup::performLookup()
{
for(Repository *&repo : m_repos) {
if(repo) {
if(repo->isBusy()) {
// repo is busy -> try again when available
connect(repo, &Repository::available, this, &SuggestionsLookup::performLookup);
} else {
// disconnect to ensure the lookup isn't done twice
disconnect(repo, nullptr, this, nullptr);
// request suggestions
QReadLocker locker(repo->lock());
if(const auto *reply = repo->requestSuggestions(m_searchTerm)) {
connect(reply, &SuggestionsReply::resultsAvailable, this, &SuggestionsLookup::addResults);
++m_remainingReplies;
} else {
m_results << repo->suggestions(m_searchTerm);
}
// this repo can be skipped when this method is called again because other repos where busy
repo = nullptr;
}
} // else: repo already processed
}
}
void SuggestionsLookup::addResults()
{
#ifdef DEBUG_BUILD
assert(m_remainingReplies);
#endif
auto *reply = static_cast<SuggestionsReply *>(sender());
{
QReadLocker locker(reply->repository()->lock());
m_results << reply->suggestions();
}
reply->deleteLater();
if(!--m_remainingReplies) {
emit resultsAvailable(QStringLiteral("suggestions"), m_id, m_results);
deleteLater();
}
}
} // namespace RepoIndex