2015-08-10 22:46:01 +02:00
# include "manager.h"
# include "database.h"
# include "utilities.h"
# include "list.h"
# include "config.h"
# include <c++utilities/io/inifile.h>
# include <c++utilities/conversion/stringconversion.h>
# include <QList>
# include <QSysInfo>
# include <QtConcurrent/QtConcurrent>
2015-08-19 02:13:28 +02:00
# include <QMutexLocker>
2015-08-10 22:46:01 +02:00
# include <fstream>
# include <iostream>
# include <unordered_map>
# include <algorithm>
using namespace std ;
using namespace IoUtilities ;
using namespace ConversionUtilities ;
namespace PackageManagement {
constexpr int defaultSigLevel = ALPM_SIG_PACKAGE | ALPM_SIG_PACKAGE_OPTIONAL |
ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL ;
/*!
* \ brief The Manager class helps accessing ALPM .
*
* - It queries the ALPM for database and package information .
* - It serializes the information as JSON objects used by the network classes and the web interface .
*/
/*!
* \ brief Creates a new manager class ; initializes a new ALPM handle .
* \ param rootdir Specifies the root directory .
* \ param dbpath Specifies the database directory .
*/
2015-08-19 02:13:28 +02:00
Manager : : Manager ( const Config & config ) :
2015-08-10 22:46:01 +02:00
m_config ( config ) ,
m_sigLevel ( defaultSigLevel ) ,
m_localFileSigLevel ( ALPM_SIG_USE_DEFAULT ) ,
m_aur ( m_networkAccessManager )
{
alpm_errno_t err ;
if ( ! ( m_handle = alpm_initialize ( config . alpmRootDir ( ) . toLocal8Bit ( ) . data ( ) , config . alpmDbPath ( ) . toLocal8Bit ( ) . data ( ) , & err ) ) ) {
throw runtime_error ( string ( " Cannot initialize alpm: " ) + alpm_strerror ( err ) ) ;
}
}
/*!
* \ brief Releases the associated ALPM handle .
*/
Manager : : ~ Manager ( )
{
alpm_release ( m_handle ) ;
}
/*!
* \ brief Returns the package with the specified name from the specified database .
*/
2015-08-19 02:13:28 +02:00
AlpmPackage Manager : : packageFromSyncDataBase ( const QString & dbName , const QString & pkgName ) const
2015-08-10 22:46:01 +02:00
{
try {
if ( dbName = = QLatin1String ( " local " ) ) {
return localDataBase ( ) . packages ( ) . at ( pkgName ) ;
} else {
return syncDataBases ( ) . at ( dbName ) . packages ( ) . at ( pkgName ) ;
}
} catch ( out_of_range & ) {
return AlpmPackage ( ) ;
}
}
/*!
* \ brief Creates a new package instance for the specified package file .
*
* Verifies the integrity of the file if the option is set .
*/
AlpmOwnershipPackage Manager : : packageFromFile ( const char * fileName , bool verifyIntegrity )
{
alpm_pkg_t * pkg ;
if ( alpm_pkg_load ( m_handle , fileName , verifyIntegrity , static_cast < alpm_siglevel_t > ( m_localFileSigLevel ) , & pkg ) ! = 0 ) {
throw runtime_error ( string ( " Unable to load package file: " ) + alpm_strerror ( alpm_errno ( m_handle ) ) ) ;
} else {
return AlpmOwnershipPackage ( pkg ) ;
}
}
/*!
* \ brief Sets the install reason for the specified \ a package .
*/
void Manager : : setInstallReason ( AlpmPackage package , alpm_pkgreason_t reason )
{
if ( alpm_pkg_set_reason ( package . ptr ( ) , reason ) ) {
throw runtime_error ( string ( " Unable to set install reason of the package " ) + package . name ( ) + " : " + alpm_strerror ( alpm_errno ( m_handle ) ) ) ;
}
}
/*!
* \ brief Returns the last value with the specified \ a key in the specified multimap .
*/
const string & lastValue ( const multimap < string , string > & mm , const string & key )
{
static const string defaultValue ;
const auto i = find_if ( mm . crbegin ( ) , mm . crend ( ) , [ & key ] ( const pair < string , string > & i ) {
return i . first = = key ;
} ) ;
return i ! = mm . crend ( ) ? i - > second : defaultValue ;
}
/*!
* \ brief Parses a " SigLevel " denotation from pacman config file .
*/
2015-08-19 02:13:28 +02:00
int Manager : : parseSigLevel ( const string & sigLevelStr )
2015-08-10 22:46:01 +02:00
{
int sigLevel = defaultSigLevel ;
// split sig level denotation into parts
const auto parts = splitString < list < string > > ( sigLevelStr , " " ) ;
for ( const auto & part : parts ) {
// determine whether part affect packages, databases or both
bool package = true , db = true ;
const char * partStart = part . data ( ) ;
if ( ! strncmp ( partStart , " Package " , 7 ) ) {
db = false ; // package only part
partStart + = 7 ;
} else if ( ! strncmp ( partStart , " Database " , 8 ) ) {
package = false ; // db only part
partStart + = 8 ;
}
// set sig level according part
if ( ! strcmp ( partStart , " Never " ) ) {
if ( package ) {
sigLevel & = ~ ALPM_SIG_PACKAGE ;
}
if ( db ) {
sigLevel & = ~ ALPM_SIG_DATABASE ;
}
} else if ( ! strcmp ( partStart , " Optional " ) ) {
if ( package ) {
sigLevel | = ALPM_SIG_PACKAGE | ALPM_SIG_PACKAGE_OPTIONAL ;
}
if ( db ) {
sigLevel | = ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL ;
}
} else if ( ! strcmp ( partStart , " Required " ) ) {
if ( package ) {
sigLevel | = ALPM_SIG_PACKAGE ;
sigLevel & = ~ ALPM_SIG_PACKAGE_OPTIONAL ;
}
if ( db ) {
sigLevel | = ALPM_SIG_DATABASE ;
sigLevel & = ~ ALPM_SIG_DATABASE_OPTIONAL ;
}
} else if ( ! strcmp ( partStart , " TrustedOnly " ) ) {
if ( package ) {
sigLevel & = ~ ( ALPM_SIG_PACKAGE_MARGINAL_OK | ALPM_SIG_PACKAGE_UNKNOWN_OK ) ;
}
if ( db ) {
sigLevel & = ~ ( ALPM_SIG_DATABASE_MARGINAL_OK | ALPM_SIG_DATABASE_UNKNOWN_OK ) ;
}
} else if ( ! strcmp ( partStart , " TrustAll " ) ) {
if ( package ) {
sigLevel | = ALPM_SIG_PACKAGE_MARGINAL_OK | ALPM_SIG_PACKAGE_UNKNOWN_OK ;
}
if ( db ) {
sigLevel | = ALPM_SIG_DATABASE_MARGINAL_OK | ALPM_SIG_DATABASE_UNKNOWN_OK ;
}
} else {
cerr < < " Warning: Invalid value \" " < < part < < " \" for \" SigLevel \" in pacman config file will be ignored. " < < endl ;
}
}
return sigLevel ;
}
/*!
* \ brief Parses a " Usage " denotation from pacman config file .
*/
2015-08-19 02:13:28 +02:00
int Manager : : parseUsage ( const string & usageStr )
2015-08-10 22:46:01 +02:00
{
int usage = 0 ;
const auto parts = splitString < list < string > > ( usageStr , " " ) ;
for ( const auto & part : parts ) {
if ( part = = " Sync " ) {
usage | = ALPM_DB_USAGE_SYNC ;
} else if ( part = = " Search " ) {
usage | = ALPM_DB_USAGE_SEARCH ;
} else if ( part = = " Install " ) {
usage | = ALPM_DB_USAGE_INSTALL ;
} else if ( part = = " Upgrade " ) {
usage | = ALPM_DB_USAGE_UPGRADE ;
} else {
cerr < < " Warning: Invalid value \" " < < part < < " \" for \" Usage \" in pacman config file will be ignored. " < < endl ;
}
}
return usage ? usage : ALPM_DB_USAGE_ALL ;
}
/*!
2015-08-19 02:13:28 +02:00
* \ brief Parses and applies the Pacman configuration . Registers the listed sync databases .
2015-08-10 22:46:01 +02:00
*/
2015-08-19 02:13:28 +02:00
void Manager : : applyPacmanConfig ( )
2015-08-10 22:46:01 +02:00
{
// open config file and parse as ini
try {
IniFile configIni ;
{
fstream configFile ;
configFile . exceptions ( ios_base : : failbit | ios_base : : badbit ) ;
configFile . open ( m_config . pacmanConfFile ( ) . toLocal8Bit ( ) . data ( ) , ios_base : : in ) ;
configIni . parse ( configFile ) ;
}
// determine current cpu archtitecture (required for server URLs)
static const string sysArch ( QSysInfo : : currentCpuArchitecture ( ) . toStdString ( ) ) ;
string arch = sysArch ;
const auto & config = configIni . data ( ) ;
// read relevant options
static const string sigLevelKey ( " SigLevel " ) ;
static const string usageKey ( " Usage " ) ;
int globalSigLevel ;
try {
const auto & options = config . at ( " options " ) ;
const auto & specifiedArch = lastValue ( options , " Architecture " ) ;
if ( ! specifiedArch . empty ( ) & & specifiedArch ! = " auto " ) {
arch = specifiedArch ;
}
const auto & specifiedDir = lastValue ( options , " CacheDir " ) ;
if ( ! specifiedDir . empty ( ) ) {
2015-08-19 02:13:28 +02:00
m_pacmanCacheDir = QString : : fromStdString ( specifiedDir ) ;
2015-08-10 22:46:01 +02:00
}
globalSigLevel = parseSigLevel ( lastValue ( options , sigLevelKey ) ) ;
} catch ( const out_of_range & ) {
// no options specified
globalSigLevel = defaultSigLevel ;
}
// register sync databases
unordered_map < string , IniFile > includedInis ;
for ( const auto & scope : config ) {
if ( scope . first ! = " options " ) {
// read and validate database name
QString dbName = QString : : fromLocal8Bit ( scope . first . c_str ( ) ) ;
2015-08-19 02:13:28 +02:00
if ( dbName . compare ( QLatin1String ( " local " ) , Qt : : CaseInsensitive ) = = 0 ) {
2015-08-10 22:46:01 +02:00
cerr < < " Error: Unable to add database from pacman config: The database name mustn't be \" local \" because this name is reserved for the local database. " < < endl ;
2015-08-19 02:13:28 +02:00
} else if ( dbName . startsWith ( QLatin1String ( " aur " ) , Qt : : CaseInsensitive ) ) {
2015-08-10 22:46:01 +02:00
cerr < < " Error: Unable to add database from pacman config: The database name mustn't start with \" aur \" because this name is reserved for the Arch Linux User Repository. " < < endl ;
} else if ( m_syncDbs . count ( dbName ) ) {
cerr < < " Error: Unable to add database from pacman config: Database names must be unique. Ignoring second occurance of database \" " < < scope . first < < " \" . " < < endl ;
} else {
// read sig level and usage
const auto & sigLevelStr = lastValue ( scope . second , sigLevelKey ) ;
int sigLevel = sigLevelStr . empty ( ) ? globalSigLevel : parseSigLevel ( sigLevelStr ) ;
int usage = parseUsage ( lastValue ( scope . second , usageKey ) ) ;
// try to register database in the ALPM system
if ( alpm_db_t * db = alpm_register_syncdb ( m_handle , scope . first . c_str ( ) , static_cast < alpm_siglevel_t > ( sigLevel ) ) ) {
// set usage
if ( alpm_db_set_usage ( db , static_cast < alpm_db_usage_t > ( usage ) ) = = 0 ) {
2015-08-19 02:13:28 +02:00
if ( m_config . isVerbose ( ) | | m_config . runServer ( ) ) {
cerr < < " Added database [ " < < scope . first < < " ] " < < endl ;
}
2015-08-10 22:46:01 +02:00
} else {
2015-08-19 02:13:28 +02:00
if ( m_config . isVerbose ( ) | | m_config . runServer ( ) ) {
cerr < < " Warning: Added database [ " < < scope . first < < " ] but failed to set usage " < < endl ;
}
2015-08-10 22:46:01 +02:00
}
// add servers
for ( auto range = scope . second . equal_range ( " Server " ) ; range . first ! = range . second ; + + range . first ) {
string url = range . first - > second ;
findAndReplace < string > ( url , " $repo " , scope . first ) ;
findAndReplace < string > ( url , " $arch " , arch ) ;
alpm_db_add_server ( db , url . c_str ( ) ) ;
2015-08-19 02:13:28 +02:00
if ( m_config . isVerbose ( ) | | m_config . runServer ( ) ) {
cerr < < " Added server: " < < url < < endl ;
}
2015-08-10 22:46:01 +02:00
}
// add included servers
for ( auto range = scope . second . equal_range ( " Include " ) ; range . first ! = range . second ; + + range . first ) {
const auto & path = range . first - > second ;
auto & includedIni = includedInis [ path ] ;
if ( includedIni . data ( ) . empty ( ) ) {
try {
fstream includedFile ;
includedFile . exceptions ( ios_base : : failbit | ios_base : : badbit ) ;
includedFile . open ( path , ios_base : : in ) ;
includedIni . parse ( includedFile ) ;
} catch ( const ios_base : : failure & ) {
cerr < < " Error: An IO exception occured when parsing the included file \" " < < path < < " \" . " < < endl ;
}
}
try {
const auto & includedScope = includedIni . data ( ) . at ( string ( ) ) ;
for ( auto range = includedScope . equal_range ( " Server " ) ; range . first ! = range . second ; + + range . first ) {
string url = range . first - > second ;
findAndReplace < string > ( url , " $repo " , scope . first ) ;
findAndReplace < string > ( url , " $arch " , arch ) ;
alpm_db_add_server ( db , url . c_str ( ) ) ;
2015-08-19 02:13:28 +02:00
if ( m_config . isVerbose ( ) | | m_config . runServer ( ) ) {
cerr < < " Added server: " < < url < < endl ;
}
2015-08-10 22:46:01 +02:00
}
} catch ( const out_of_range & ) {
cerr < < " Warning: Included file \" " < < path < < " \" has no values. " < < endl ;
}
}
// add sync db to internal map
if ( usage & ALPM_DB_USAGE_UPGRADE ) {
// -> db is used to upgrade local database
localDataBase ( ) . upgradeSources ( ) < < dbName ;
}
2015-08-19 02:13:28 +02:00
m_syncDbs . emplace ( dbName , AlpmDataBase ( db , QStringLiteral ( " %1/sync/%2 " ) . arg ( m_config . alpmDbPath ( ) , dbName ) ) ) ;
2015-08-10 22:46:01 +02:00
} else {
2015-08-19 02:13:28 +02:00
cerr < < " Error: Unable to add sync database [ " < < scope . first < < " ] " < < endl ;
2015-08-10 22:46:01 +02:00
}
}
}
}
} catch ( const ios_base : : failure & ) {
2015-08-19 02:13:28 +02:00
throw ios_base : : failure ( " Error: An IO exception occured when parsing the config file. " ) ;
}
}
/*!
* \ brief Applies the repository index configuration .
*/
void Manager : : applyRepoIndexConfig ( )
{
for ( const RepoEntry & repoEntry : m_config . repoEntries ( ) ) {
AlpmDataBase * syncDb ;
try {
syncDb = & m_syncDbs . at ( repoEntry . name ( ) ) ;
cerr < < " Applying config for database [ " < < syncDb - > name ( ) < < " ] " < < endl ;
if ( ! repoEntry . dataBasePath ( ) . isEmpty ( ) ) {
cerr < < " Warning: Can't use data base path specified in repo index config because the repo \" "
< < repoEntry . name ( ) . toLocal8Bit ( ) . data ( ) < < " \" has already been added from the Pacman config. " < < endl ;
}
if ( repoEntry . sigLevel ( ) ) {
cerr < < " Warning: Can't use sig level path specified in repo index config because the repo \" "
< < repoEntry . name ( ) . toLocal8Bit ( ) . data ( ) < < " \" has already been added from the Pacman config. " < < endl ;
}
syncDb - > setPackagesDirectory ( repoEntry . packageDir ( ) ) ;
syncDb - > setSourcesDirectory ( repoEntry . sourceDir ( ) ) ;
} catch ( const out_of_range & ) {
if ( repoEntry . name ( ) . compare ( QLatin1String ( " local " ) , Qt : : CaseInsensitive ) = = 0 ) {
cerr < < " Error: Unable to add database from repo index config: The database name mustn't be \" local \" because this name is reserved for the local database. " < < endl ;
} else if ( repoEntry . name ( ) . startsWith ( QLatin1String ( " aur " ) , Qt : : CaseInsensitive ) ) {
cerr < < " Error: Unable to add database from repo index config: The database name mustn't start with \" aur \" because this name is reserved for the Arch Linux User Repository. " < < endl ;
} else {
auto * db = alpm_register_syncdb ( m_handle , repoEntry . name ( ) . toLocal8Bit ( ) . data ( ) , static_cast < alpm_siglevel_t > ( repoEntry . sigLevel ( ) ) ) ;
auto emplaced = m_syncDbs . emplace ( repoEntry . name ( ) , AlpmDataBase ( db , repoEntry . dataBasePath ( ) , repoEntry . sourceDir ( ) , repoEntry . packageDir ( ) ) ) ;
if ( emplaced . second ) {
syncDb = & emplaced . first - > second ;
if ( m_config . isVerbose ( ) | | m_config . runServer ( ) ) {
cerr < < " Added database [ " < < repoEntry . name ( ) . toLocal8Bit ( ) . data ( ) < < " ] " < < endl ;
}
}
}
}
if ( syncDb ) {
syncDb - > addServerUrls ( repoEntry . servers ( ) ) ;
syncDb - > upgradeSources ( ) < < repoEntry . upgradeSources ( ) ;
}
2015-08-10 22:46:01 +02:00
}
}
/*!
* \ brief Unregisters all registred sync databases .
*/
void Manager : : unregisterSyncDataBases ( )
{
if ( alpm_unregister_all_syncdbs ( m_handle ) ) {
throw runtime_error ( string ( " Cannot unregister sync databases: " ) + alpm_strerror ( alpm_errno ( m_handle ) ) ) ;
}
}
/*!
* \ brief Returns the local data base .
*/
const AlpmDataBase & Manager : : localDataBase ( ) const
{
if ( ! m_localDb ) {
2015-08-19 02:13:28 +02:00
QMutexLocker locker ( & m_localDbMutex ) ;
if ( ! m_localDb ) {
m_localDb = alpm_get_localdb ( m_handle ) ;
}
2015-08-10 22:46:01 +02:00
}
return m_localDb ;
}
/*!
* \ brief Returns the local data base .
*/
AlpmDataBase & Manager : : localDataBase ( )
{
if ( ! m_localDb ) {
m_localDb = alpm_get_localdb ( m_handle ) ;
}
return m_localDb ;
}
/*!
* \ brief Returns a list of all sync databases .
* \ remarks Sync databases must be registered with parsePacmanConfig ( ) before .
*/
const std : : map < QString , AlpmDataBase > & Manager : : syncDataBases ( ) const
{
return m_syncDbs ; // m_syncDbs has been filled when the databases were registered
}
/*!
* \ brief Returns basic information about the specified repository .
*/
QJsonObject Manager : : basicRepoInfo ( AlpmDataBase db , const QString & name , const QString & desc ) const
{
QJsonObject repoInfo ;
repoInfo . insert ( QStringLiteral ( " name " ) , name ) ;
repoInfo . insert ( QStringLiteral ( " desc " ) , desc ) ;
repoInfo . insert ( QStringLiteral ( " servers " ) , db . serverUrls ( ) ) ;
repoInfo . insert ( QStringLiteral ( " usage " ) , Utilities : : usageStrings ( db . usage ( ) ) ) ;
repoInfo . insert ( QStringLiteral ( " sigLevel " ) , Utilities : : sigLevelStrings ( db . sigLevel ( ) ) ) ;
2015-08-19 02:13:28 +02:00
repoInfo . insert ( QStringLiteral ( " upgradeSources " ) , QJsonArray : : fromStringList ( db . upgradeSources ( ) ) ) ;
2015-08-10 22:46:01 +02:00
repoInfo . insert ( QStringLiteral ( " packages " ) , db . packageNameJsonArray ( ) ) ;
return repoInfo ;
}
/*!
* \ brief Returns basic information about all repositories known to the manager .
*
* The results include the local database ( " local " ) and the names of
* the registered sync databases .
*/
const QJsonArray & Manager : : basicRepoInfo ( ) const
{
if ( m_basicRepoInfo . isEmpty ( ) ) {
2015-08-19 02:13:28 +02:00
QMutexLocker locker ( & m_basicRepoInfoMutex ) ;
if ( m_basicRepoInfo . isEmpty ( ) ) {
m_basicRepoInfo < < basicRepoInfo ( localDataBase ( ) , QStringLiteral ( " local " ) , QStringLiteral ( " The local database. " ) ) ;
auto const & syncDbs = syncDataBases ( ) ;
for ( const auto & syncDb : syncDbs ) {
// check if the "sync" database is actually used for syncing
auto usage = syncDb . second . usage ( ) ;
if ( ( usage & ALPM_DB_USAGE_SYNC ) | | ( usage & ALPM_DB_USAGE_INSTALL ) | | ( usage & ALPM_DB_USAGE_UPGRADE ) ) {
m_basicRepoInfo < < basicRepoInfo ( syncDb . second , syncDb . first , QStringLiteral ( " The sync database »%1«. " ) . arg ( syncDb . first ) ) ;
} else {
m_basicRepoInfo < < basicRepoInfo ( syncDb . second , syncDb . first , QStringLiteral ( " The database »%1«. " ) . arg ( syncDb . first ) ) ;
}
2015-08-10 22:46:01 +02:00
}
}
}
return m_basicRepoInfo ;
}
/*!
* \ brief Returns package information for the specified selection of packages .
*/
2015-08-19 02:13:28 +02:00
const QJsonArray Manager : : packageInfo ( const QJsonArray & pkgSelection , bool full ) const
2015-08-10 22:46:01 +02:00
{
QJsonArray pkgInfos ;
for ( const auto & pkgSelJsonVal : pkgSelection ) {
QJsonObject pkgSel = pkgSelJsonVal . toObject ( ) ;
if ( ! pkgSel . isEmpty ( ) ) {
QString repoName = pkgSel . value ( QStringLiteral ( " repo " ) ) . toString ( ) ;
QString pkgName = pkgSel . value ( QStringLiteral ( " name " ) ) . toString ( ) ;
AlpmPackage pkg ;
QJsonObject pkgInfo ;
if ( ! repoName . isEmpty ( ) & & ! pkgName . isEmpty ( ) & & ( pkg = packageFromSyncDataBase ( repoName , pkgName ) ) ) {
pkgInfo = full ? pkg . fullInfo ( ) : pkg . basicInfo ( ) ;
} else {
pkgInfo . insert ( QStringLiteral ( " error " ) , QStringLiteral ( " na " ) ) ;
}
pkgInfo . insert ( QStringLiteral ( " name " ) , pkgName ) ;
pkgInfo . insert ( QStringLiteral ( " repo " ) , repoName ) ;
pkgInfo . insert ( QStringLiteral ( " index " ) , pkgSel . value ( QStringLiteral ( " index " ) ) ) ;
pkgInfos < < pkgInfo ;
}
}
return pkgInfos ;
}
/*!
* \ brief Returns group information for the local database and all registred sync databases .
*/
const QJsonArray & Manager : : groupInfo ( ) const
{
if ( m_groupInfo . empty ( ) ) {
2015-08-19 02:13:28 +02:00
QMutexLocker locker ( & m_groupInfoMutex ) ;
if ( m_groupInfo . empty ( ) ) {
m_groupInfo < < localDataBase ( ) . groupInfo ( ) ;
for ( const auto & db : m_syncDbs ) {
m_groupInfo < < db . second . groupInfo ( ) ;
}
2015-08-10 22:46:01 +02:00
}
}
return m_groupInfo ;
}
/*!
* \ brief Returns the ALPM database with the specified name .
* \ throws Throws std : : out_of_range if the specified database is unknown to the manager .
*/
const AlpmDataBase & Manager : : dataBaseByName ( const QString & dbName ) const
{
if ( dbName = = QLatin1String ( " local " ) ) {
return localDataBase ( ) ;
} else {
return m_syncDbs . at ( dbName ) ;
}
}
/*!
* \ brief Returns the ALPM database with the specified name .
* \ throws Throws std : : out_of_range if the specified database is unknown to the manager .
*/
AlpmDataBase & Manager : : dataBaseByName ( const QString & dbName )
{
if ( dbName = = QLatin1String ( " local " ) ) {
return localDataBase ( ) ;
} else {
return m_syncDbs . at ( dbName ) ;
}
}
/*!
* \ brief Checks for upgrades availabel to the specified database .
*
* The \ a request must have the following values :
* - db : Specifies the name of the database to check for upgrades .
* - syncdbs : Array with the names of the databases used as upgrade sources .
* If not present , appropriate upgrade sources will be determined automatically .
*/
2015-08-19 02:13:28 +02:00
void Manager : : invokeUpgradeLookup ( const QJsonObject & request , UpdateLookupCallback callback ) const
2015-08-10 22:46:01 +02:00
{
2015-08-19 02:13:28 +02:00
new UpdateLookup ( * this , request , callback ) ; // this object will delete itself
2015-08-10 22:46:01 +02:00
}
/*!
* \ brief Checks the specified database for upgrades .
*
2015-08-19 02:13:28 +02:00
* Appropriate upgrade sources will be determined automatically ; does not check the AUR .
2015-08-10 22:46:01 +02:00
*/
2015-08-19 02:13:28 +02:00
const UpdateLookupResults < AlpmPackage > Manager : : checkForUpgrades ( const AlpmDataBase & db ) const
2015-08-10 22:46:01 +02:00
{
2015-08-19 02:13:28 +02:00
UpdateLookupResults < AlpmPackage > results ;
2015-08-10 22:46:01 +02:00
QList < const AlpmDataBase * > syncDbSel ;
for ( const auto & syncDbName : db . upgradeSources ( ) ) {
try {
syncDbSel < < & ( syncDataBases ( ) . at ( syncDbName ) ) ;
} catch ( out_of_range & ) {
;
}
}
db . checkForUpgrades ( syncDbSel , results ) ;
return results ;
}
}