repoindex/alpm/alpmdatabase.cpp

135 lines
3.4 KiB
C++

#include "./alpmdatabase.h"
#include "./group.h"
#include "./upgradelookup.h"
#include "./alpmpackage.h"
#include "./utilities.h"
#include <c++utilities/misc/memory.h>
#include <alpm.h>
#include <QList>
#include <QJsonObject>
#include <QtConcurrent>
using namespace std;
namespace RepoIndex {
using namespace Utilities;
/*!
* \class AlpmDatabase
* \brief The AlpmDatabase class wraps an ALPM data base struct and holds additional meta information.
*
* All packages returned by the AlpmDatabase class are AlpmPackage instances.
*/
class LoadPackage
{
public:
LoadPackage(AlpmDatabase *db, QMutex *mutex) :
m_db(db),
m_mutex(mutex)
{}
void operator()(alpm_pkg_t *pkg)
{
auto res = make_unique<AlpmPackage>(pkg, m_db);
QMutexLocker locker(m_mutex);
for(const auto &grpName : res->groups()) {
m_db->groups()[grpName] << res.get();
}
m_db->packages().emplace(res->name(), move(res));
}
private:
AlpmDatabase *m_db;
QMutex *m_mutex;
};
AlpmPackageLoader::AlpmPackageLoader(AlpmDatabase *repository)
{
for(auto *pkg : PackageList(alpm_db_get_pkgcache(repository->ptr()))) {
m_packages << pkg;
}
m_future = QtConcurrent::map(m_packages, LoadPackage(repository, &m_mutex));
}
/*!
* \brief Creates a new instance wrapping the specified database struct.
*/
AlpmDatabase::AlpmDatabase(alpm_db_t *dataBase, const QString &dbPath, uint32 index, QObject *parent) :
Repository(QString::fromLocal8Bit(alpm_db_get_name(dataBase)), index, parent),
m_ptr(dataBase),
m_dbFile(QStringLiteral("%1/sync/%2").arg(dbPath, m_name))
{}
AlpmPackageLoader *AlpmDatabase::init()
{
if(alpm_db_get_usage(m_ptr, &m_usage)) {
m_usage = static_cast<decltype(m_usage)>(ALPM_DB_USAGE_ALL);
}
if(m_name.compare(QLatin1String("local"), Qt::CaseInsensitive) == 0) {
m_description = QStringLiteral("The local database");
} else {
if((m_usage & ALPM_DB_USAGE_SYNC) || (m_usage & ALPM_DB_USAGE_INSTALL) || (m_usage & ALPM_DB_USAGE_UPGRADE)) {
m_description = QStringLiteral("Sync database »%1«").arg(m_name);
} else {
m_description = QStringLiteral("Database »%1«").arg(m_name);
}
}
for(const char *str : servers()) {
m_serverUrls << qstr(str);
}
m_sigLevel = alpm_db_get_siglevel(m_ptr);
return new AlpmPackageLoader(this);
}
//AlpmDatabase::AlpmDatabase(const QString &dataBaseFile, QObject *parent) :
// PackageSource(parent),
// m_ptr(nullptr)
//{}
RepositoryType AlpmDatabase::type() const
{
return RepositoryType::AlpmDatabase;
}
PackageDetailAvailability AlpmDatabase::requestsRequired(PackageDetail packageDetail) const
{
switch(packageDetail) {
case PackageDetail::Basics:
case PackageDetail::Dependencies:
case PackageDetail::PackageInfo:
case PackageDetail::AllAvailable:
return PackageDetailAvailability::Immediately;
default:
return PackageDetailAvailability::Never;
}
}
/*!
* \brief Adds the specified server URLs.
*/
bool AlpmDatabase::addServerUrls(const QStringList &urls)
{
bool res = true;
for(const auto &url : urls) {
if(alpm_db_add_server(m_ptr, url.toLocal8Bit().data()) != 0) {
res = false;
} else {
m_serverUrls << url;
}
}
return res;
}
std::unique_ptr<Package> AlpmDatabase::emptyPackage()
{
return make_unique<AlpmPackage>(this);
}
} // namespace Alpm