/** \file zypp/sat/Repository.cc
*
*/
+#include <climits>
#include <iostream>
#include "zypp/base/Logger.h"
#include "zypp/base/Gettext.h"
#include "zypp/base/Exception.h"
+#include "zypp/base/Xml.h"
#include "zypp/AutoDispose.h"
#include "zypp/Pathname.h"
#include "zypp/sat/detail/PoolImpl.h"
#include "zypp/Repository.h"
+#include "zypp/ResPool.h"
+#include "zypp/Product.h"
#include "zypp/sat/Pool.h"
using std::endl;
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////
const Repository Repository::noRepository;
+ const std::string & Repository::systemRepoAlias()
+ { return sat::detail::PoolImpl::systemRepoAlias(); }
+
/////////////////////////////////////////////////////////////////
::_Repo * Repository::get() const
bool Repository::isSystemRepo() const
{
NO_REPOSITORY_RETURN( false );
- return( sat::Pool::systemRepoName() == _repo->name );
+ return myPool().isSystemRepo( _repo );
+ }
+
+ std::string Repository::alias() const
+ {
+ NO_REPOSITORY_RETURN( std::string() );
+ if ( ! _repo->name )
+ return std::string();
+ return _repo->name;
}
std::string Repository::name() const
+ { return info().name(); }
+
+ std::string Repository::label() const
+ { return info().label(); }
+
+ int Repository::satInternalPriority() const
+ {
+ NO_REPOSITORY_RETURN( INT_MIN );
+ return _repo->priority;
+ }
+
+ int Repository::satInternalSubPriority() const
+ {
+ NO_REPOSITORY_RETURN( INT_MIN );
+ return _repo->subpriority;
+ }
+
+ Repository::ContentRevision Repository::contentRevision() const
+ {
+ NO_REPOSITORY_RETURN( ContentRevision() );
+ sat::LookupRepoAttr q( sat::SolvAttr::repositoryRevision, *this );
+ return q.empty() ? std::string() : q.begin().asString();
+ }
+
+ Repository::ContentIdentifier Repository::contentIdentifier() const
+ {
+ NO_REPOSITORY_RETURN( ContentIdentifier() );
+ sat::LookupRepoAttr q( sat::SolvAttr::repositoryRepoid, *this );
+ return q.empty() ? std::string() : q.begin().asString();
+ }
+
+ bool Repository::hasContentIdentifier( const ContentIdentifier & id_r ) const
+ {
+ NO_REPOSITORY_RETURN( false );
+ sat::LookupRepoAttr q( sat::SolvAttr::repositoryRepoid, *this );
+ for_( it, q.begin(), q.end() )
+ if ( it.asString() == id_r )
+ return true;
+ return false;
+ }
+
+ zypp::Date Repository::generatedTimestamp() const
+ {
+ NO_REPOSITORY_RETURN( 0 );
+ sat::LookupRepoAttr q( sat::SolvAttr::repositoryTimestamp, *this );
+ return( q.empty() ? 0 : q.begin().asUnsigned() );
+ }
+
+ zypp::Date Repository::suggestedExpirationTimestamp() const
+ {
+ NO_REPOSITORY_RETURN( 0 );
+ Date generated = generatedTimestamp();
+ if ( ! generated )
+ return 0; // do not calculate over a missing generated timestamp
+
+ sat::LookupRepoAttr q( sat::SolvAttr::repositoryExpire, *this );
+ if ( q.empty() )
+ return 0;
+
+ return generated + Date(q.begin().asUnsigned());
+ }
+
+ Repository::Keywords Repository::keywords() const
+ {
+ NO_REPOSITORY_RETURN( Keywords() );
+ return Keywords( sat::SolvAttr::repositoryKeywords, *this, sat::LookupAttr::REPO_ATTR );
+ }
+
+ bool Repository::hasKeyword( const std::string & val_r ) const
+ {
+ for ( const auto & val : keywords() )
+ if ( val == val_r )
+ return true;
+ return false;
+ }
+
+ bool Repository::maybeOutdated() const
+ {
+ NO_REPOSITORY_RETURN( false );
+ // system repo is not mirrored
+ if ( isSystemRepo() )
+ return false;
+
+ Date suggested = suggestedExpirationTimestamp();
+
+ // if no data, don't suggest
+ if ( ! suggested )
+ return false;
+
+ return suggestedExpirationTimestamp() < Date::now();
+ }
+
+ bool Repository::providesUpdatesFor( const CpeId & cpeid_r ) const
+ {
+ NO_REPOSITORY_RETURN( false );
+ if ( ! cpeid_r )
+ return false; // filter queries/products without CpeId, as an empty CpeId matches ANYthing.
+
+ // check in repository metadata
+ for_( it, updatesProductBegin(), updatesProductEnd() )
+ {
+ if ( compare( cpeid_r, it.cpeId(), SetRelation::subset ) )
+ return true;
+ }
+
+ // check whether known products refer to this as update repo
+ sat::LookupRepoAttr myIds( sat::SolvAttr::repositoryRepoid, *this ); // usually just one, but...
+ if ( ! myIds.empty() )
+ {
+ const ResPool & pool( ResPool::instance() );
+ for_( it, pool.byKindBegin<Product>(), pool.byKindEnd<Product>() )
+ {
+ Product::constPtr prod( (*it)->asKind<Product>() );
+ if ( compare( cpeid_r, prod->cpeId(), SetRelation::superset ) )
+ {
+ for_( myId, myIds.begin(), myIds.end() )
+ {
+ if ( prod->hasUpdateContentIdentifier( myId.asString() ) )
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ bool Repository::isUpdateRepo() const
{
- NO_REPOSITORY_RETURN( std::string() );
- if ( ! _repo->name )
- return std::string();
- return _repo->name;
+ NO_REPOSITORY_RETURN( false );
+
+ // check in repository metadata
+ if ( updatesProductBegin() != updatesProductEnd() )
+ return true;
+
+ // check whether known products refer to this as update repo
+ sat::LookupRepoAttr myIds( sat::SolvAttr::repositoryRepoid, *this ); // usually just one, but...
+ if ( ! myIds.empty() )
+ {
+ const ResPool & pool( ResPool::instance() );
+ for_( it, pool.byKindBegin<Product>(), pool.byKindEnd<Product>() )
+ {
+ for_( myId, myIds.begin(), myIds.end() )
+ {
+ if ( (*it)->asKind<Product>()->hasUpdateContentIdentifier( myId.asString() ) )
+ return true;
+ }
+ }
+ }
+ return false;
}
bool Repository::solvablesEmpty() const
{
- NO_REPOSITORY_RETURN( true );
- return _repo->nsolvables;
+ NO_REPOSITORY_RETURN( true );
+ return !_repo->nsolvables;
}
Repository::size_type Repository::solvablesSize() const
{
- NO_REPOSITORY_RETURN( 0 );
- return _repo->nsolvables;
+ NO_REPOSITORY_RETURN( 0 );
+ return _repo->nsolvables;
}
Repository::SolvableIterator Repository::solvablesBegin() const
{
- NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
- sat::detail::SolvableIterator(),
- sat::detail::SolvableIterator() ) );
- return make_filter_iterator( detail::ByRepository( *this ),
- sat::detail::SolvableIterator(_repo->start),
- sat::detail::SolvableIterator(_repo->end) );
+ NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
+ sat::detail::SolvableIterator(),
+ sat::detail::SolvableIterator() ) );
+ return make_filter_iterator( detail::ByRepository( *this ),
+ sat::detail::SolvableIterator(_repo->start),
+ sat::detail::SolvableIterator(_repo->end) );
}
Repository::SolvableIterator Repository::solvablesEnd() const
{
- NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
- sat::detail::SolvableIterator(),
- sat::detail::SolvableIterator() ) );
- return make_filter_iterator(detail::ByRepository( *this ),
- sat::detail::SolvableIterator(_repo->end),
- sat::detail::SolvableIterator(_repo->end) );
+ NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
+ sat::detail::SolvableIterator(),
+ sat::detail::SolvableIterator() ) );
+ return make_filter_iterator(detail::ByRepository( *this ),
+ sat::detail::SolvableIterator(_repo->end),
+ sat::detail::SolvableIterator(_repo->end) );
+ }
+
+ Repository::ProductInfoIterator Repository::compatibleWithProductBegin() const
+ {
+ NO_REPOSITORY_RETURN( ProductInfoIterator() );
+ return ProductInfoIterator( sat::SolvAttr::repositoryDistros, *this );
+ }
+
+ Repository::ProductInfoIterator Repository::compatibleWithProductEnd() const
+ {
+ return ProductInfoIterator();
+ }
+
+ Repository::ProductInfoIterator Repository::updatesProductBegin() const
+ {
+ NO_REPOSITORY_RETURN( ProductInfoIterator() );
+ return ProductInfoIterator( sat::SolvAttr::repositoryUpdates, *this );
+ }
+
+ Repository::ProductInfoIterator Repository::updatesProductEnd() const
+ {
+ return ProductInfoIterator();
}
RepoInfo Repository::info() const
{
- NO_REPOSITORY_RETURN( RepoInfo() );
- return myPool().repoInfo( _repo );
+ NO_REPOSITORY_RETURN( RepoInfo() );
+ return myPool().repoInfo( _repo );
}
void Repository::setInfo( const RepoInfo & info_r )
{
- NO_REPOSITORY_THROW( Exception( _("Can't set RepoInfo for norepo.") ) );
- if ( info_r.alias() != name() )
+ NO_REPOSITORY_THROW( Exception( "Can't set RepoInfo for norepo." ) );
+ if ( info_r.alias() != alias() )
{
- ZYPP_THROW( Exception( str::form( _("RepoInfo alias (%s) does not match repository name (%s)"),
- info_r.alias().c_str(), name().c_str() ) ) );
+ ZYPP_THROW( Exception( str::form( "RepoInfo alias (%s) does not match repository alias (%s)",
+ info_r.alias().c_str(), alias().c_str() ) ) );
}
myPool().setRepoInfo( _repo, info_r );
-
- // satsolver priority is based on '<', while yum's repoinfo
- // uses 1(highest)->99(lowest). Thus we use -info_r.priority.
- _repo->priority = -info_r.priority();
+ MIL << *this << endl;
}
void Repository::clearInfo()
void Repository::eraseFromPool()
{
NO_REPOSITORY_RETURN();
+ MIL << *this << " removed from pool" << endl;
myPool()._deleteRepo( _repo );
_id = sat::detail::noRepoId;
}
-#warning NEED POOL MANIP EXEPTIONS
+ Repository Repository::nextInPool() const
+ {
+ NO_REPOSITORY_RETURN( noRepository );
+ for_( it, sat::Pool::instance().reposBegin(), sat::Pool::instance().reposEnd() )
+ {
+ if ( *it == *this )
+ {
+ if ( ++it != _for_end )
+ return *it;
+ break;
+ }
+ }
+ return noRepository;
+ }
+
void Repository::addSolv( const Pathname & file_r )
{
- NO_REPOSITORY_THROW( Exception( _("Can't add solvables to norepo.") ) );
+ NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo." ) );
- AutoDispose<FILE*> file( ::fopen( file_r.c_str(), "r" ), ::fclose );
- if ( file == NULL )
- {
- file.resetDispose();
- ZYPP_THROW( Exception( _("Can't open solv-file: ")+file_r.asString() ) );
- }
+ AutoDispose<FILE*> file( ::fopen( file_r.c_str(), "re" ), ::fclose );
+ if ( file == NULL )
+ {
+ file.resetDispose();
+ ZYPP_THROW( Exception( "Can't open solv-file: "+file_r.asString() ) );
+ }
- if ( myPool()._addSolv( _repo, file, isSystemRepo() ) != 0 )
- {
- ZYPP_THROW( Exception( _("Error reading solv-file: ")+file_r.asString() ) );
- }
+ if ( myPool()._addSolv( _repo, file ) != 0 )
+ {
+ ZYPP_THROW( Exception( "Error reading solv-file: "+file_r.asString() ) );
+ }
+
+ MIL << *this << " after adding " << file_r << endl;
+ }
+
+ void Repository::addHelix( const Pathname & file_r )
+ {
+ NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo." ) );
+
+ std::string command( file_r.extension() == ".gz" ? "zcat " : "cat " );
+ command += file_r.asString();
+
+ AutoDispose<FILE*> file( ::popen( command.c_str(), "re" ), ::pclose );
+ if ( file == NULL )
+ {
+ file.resetDispose();
+ ZYPP_THROW( Exception( "Can't open helix-file: "+file_r.asString() ) );
+ }
+
+ if ( myPool()._addHelix( _repo, file ) != 0 )
+ {
+ ZYPP_THROW( Exception( "Error reading helix-file: "+file_r.asString() ) );
+ }
+
+ MIL << *this << " after adding " << file_r << endl;
}
sat::detail::SolvableIdType Repository::addSolvables( unsigned count_r )
{
- NO_REPOSITORY_THROW( Exception( _("Can't add solvables to norepo.") ) );
+ NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo.") );
return myPool()._addSolvables( _repo, count_r );
}
std::ostream & operator<<( std::ostream & str, const Repository & obj )
{
if ( ! obj )
- return str << "sat::repo()";
+ return str << "noRepository";
- return str << "sat::repo(" << obj.name() << ")"
+ return str << "sat::repo(" << obj.alias() << ")"
<< "{"
- << "prio " << obj.get()->priority
+ << "prio " << obj.get()->priority << '.' << obj.get()->subpriority
<< ", size " << obj.solvablesSize()
- <<"}";
+ << "}";
+ }
+
+ std::ostream & dumpAsXmlOn( std::ostream & str, const Repository & obj )
+ {
+ return xmlout::node( str, "repository", {
+ { "name", obj.name() },
+ { "alias", obj.alias() }
+ } );
}
+ //////////////////////////////////////////////////////////////////
+ namespace detail
+ {
+ void RepositoryIterator::increment()
+ {
+ if ( base() )
+ {
+ ::_Pool * satpool = sat::Pool::instance().get();
+ do {
+ ++base_reference();
+ } while ( base() < satpool->repos+satpool->nrepos && !*base() );
+ }
+ }
+ } // namespace detail
+ //////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // Repository::ProductInfoIterator
+ //
+ ///////////////////////////////////////////////////////////////////
+
+ Repository::ProductInfoIterator::ProductInfoIterator( sat::SolvAttr attr_r, Repository repo_r )
+ { base_reference() = sat::LookupRepoAttr( attr_r, repo_r ).begin(); }
+
+ std::string Repository::ProductInfoIterator::label() const
+ { return base_reference().subFind( sat::SolvAttr::repositoryProductLabel ).asString(); }
+
+ CpeId Repository::ProductInfoIterator::cpeId() const
+ { return CpeId( base_reference().subFind( sat::SolvAttr::repositoryProductCpeid ).asString(), CpeId::noThrow ); }
/////////////////////////////////////////////////////////////////
} // namespace zypp