libzypp  10.5.0
Repository.cc
Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <climits>
00013 #include <iostream>
00014 
00015 #include "zypp/base/Logger.h"
00016 #include "zypp/base/Gettext.h"
00017 #include "zypp/base/Exception.h"
00018 
00019 #include "zypp/AutoDispose.h"
00020 #include "zypp/Pathname.h"
00021 
00022 #include "zypp/sat/detail/PoolImpl.h"
00023 #include "zypp/Repository.h"
00024 #include "zypp/sat/Pool.h"
00025 
00026 using std::endl;
00027 
00029 namespace zypp
00030 { 
00031 
00032     const Repository Repository::noRepository;
00033 
00034     const std::string & Repository::systemRepoAlias()
00035     { return sat::detail::PoolImpl::systemRepoAlias(); }
00036 
00038 
00039     ::_Repo * Repository::get() const
00040     { return myPool().getRepo( _id ); }
00041 
00042 #define NO_REPOSITORY_RETURN( VAL ) \
00043     ::_Repo * _repo( get() ); \
00044     if ( ! _repo ) return VAL
00045 
00046 #define NO_REPOSITORY_THROW( VAL ) \
00047     ::_Repo * _repo( get() ); \
00048     if ( ! _repo ) ZYPP_THROW( VAL )
00049 
00050     bool Repository::isSystemRepo() const
00051     {
00052         NO_REPOSITORY_RETURN( false );
00053         return myPool().isSystemRepo( _repo );
00054     }
00055 
00056     std::string Repository::alias() const
00057     {
00058       NO_REPOSITORY_RETURN( std::string() );
00059       if ( ! _repo->name )
00060         return std::string();
00061       return _repo->name;
00062     }
00063 
00064     std::string Repository::name() const
00065     { return info().name(); }
00066 
00067     int Repository::satInternalPriority() const
00068     {
00069       NO_REPOSITORY_RETURN( INT_MIN );
00070       return _repo->priority;
00071     }
00072 
00073     int Repository::satInternalSubPriority() const
00074     {
00075       NO_REPOSITORY_RETURN( INT_MIN );
00076       return _repo->subpriority;
00077     }
00078 
00079 
00080     zypp::Date Repository::generatedTimestamp() const
00081     {
00082       NO_REPOSITORY_RETURN( 0 );
00083       sat::LookupRepoAttr q( sat::SolvAttr::repositoryTimestamp, *this );
00084       return( q.empty() ? 0 : q.begin().asUnsigned() );
00085     }
00086 
00087     zypp::Date Repository::suggestedExpirationTimestamp() const
00088     {
00089       NO_REPOSITORY_RETURN( 0 );
00090       Date generated = generatedTimestamp();
00091       if ( ! generated )
00092         return 0; // do not calculate over a missing generated timestamp
00093 
00094       sat::LookupRepoAttr q( sat::SolvAttr::repositoryExpire, *this );
00095       if ( q.empty() )
00096         return 0;
00097 
00098       return generated + q.begin().asUnsigned();
00099     }
00100 
00101     Repository::Keywords Repository::keywords() const
00102     {
00103       NO_REPOSITORY_RETURN( Keywords() );
00104       return Keywords( sat::SolvAttr::repositoryKeywords, *this, sat::LookupAttr::REPO_ATTR );
00105     }
00106 
00107     bool Repository::maybeOutdated() const
00108     {
00109       NO_REPOSITORY_RETURN( false );
00110       // system repo is not mirrored
00111       if ( isSystemRepo() )
00112         return false;
00113 
00114       Date suggested = suggestedExpirationTimestamp();
00115 
00116       // if no data, don't suggest
00117       if ( ! suggested )
00118         return false;
00119 
00120       return suggestedExpirationTimestamp() < Date::now();
00121     }
00122 
00123     bool Repository::providesUpdatesFor( const std::string &key ) const
00124     {
00125       NO_REPOSITORY_RETURN( false );
00126 
00127       for_( it,
00128             updatesProductBegin(),
00129             updatesProductEnd() )
00130       {
00131         // FIXME implement real CPE matching here
00132         // someday
00133         if ( key == it.cpeId() )
00134           return true;
00135       }
00136 
00137       return false;
00138     }
00139 
00140     bool Repository::isUpdateRepo() const
00141     {
00142       NO_REPOSITORY_RETURN( false );
00143       return ( updatesProductBegin() != updatesProductEnd() );
00144     }
00145 
00146     bool Repository::solvablesEmpty() const
00147     {
00148       NO_REPOSITORY_RETURN( true );
00149       return !_repo->nsolvables;
00150     }
00151 
00152     Repository::size_type Repository::solvablesSize() const
00153     {
00154       NO_REPOSITORY_RETURN( 0 );
00155       return _repo->nsolvables;
00156     }
00157 
00158     Repository::SolvableIterator Repository::solvablesBegin() const
00159     {
00160       NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
00161                             sat::detail::SolvableIterator(),
00162                             sat::detail::SolvableIterator() ) );
00163       return make_filter_iterator( detail::ByRepository( *this ),
00164                                    sat::detail::SolvableIterator(_repo->start),
00165                                    sat::detail::SolvableIterator(_repo->end) );
00166     }
00167 
00168     Repository::SolvableIterator Repository::solvablesEnd() const
00169     {
00170       NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
00171                             sat::detail::SolvableIterator(),
00172                             sat::detail::SolvableIterator() ) );
00173       return make_filter_iterator(detail::ByRepository( *this ),
00174                                   sat::detail::SolvableIterator(_repo->end),
00175                                   sat::detail::SolvableIterator(_repo->end) );
00176     }
00177 
00178     Repository::ProductInfoIterator Repository::compatibleWithProductBegin() const
00179     {
00180       NO_REPOSITORY_RETURN( ProductInfoIterator() );
00181       return ProductInfoIterator( sat::SolvAttr::repositoryDistros, *this );
00182     }
00183 
00184     Repository::ProductInfoIterator Repository::compatibleWithProductEnd() const
00185     {
00186       return ProductInfoIterator();
00187     }
00188 
00189     Repository::ProductInfoIterator Repository::updatesProductBegin() const
00190     {
00191       NO_REPOSITORY_RETURN( ProductInfoIterator() );
00192       return ProductInfoIterator( sat::SolvAttr::repositoryUpdates, *this );
00193     }
00194 
00195     Repository::ProductInfoIterator Repository::updatesProductEnd() const
00196     {
00197       return ProductInfoIterator();
00198     }
00199 
00200     RepoInfo Repository::info() const
00201     {
00202       NO_REPOSITORY_RETURN( RepoInfo() );
00203       return myPool().repoInfo( _repo );
00204     }
00205 
00206     void Repository::setInfo( const RepoInfo & info_r )
00207     {
00208         NO_REPOSITORY_THROW( Exception( "Can't set RepoInfo for norepo." ) );
00209         if ( info_r.alias() != alias() )
00210         {
00211             ZYPP_THROW( Exception( str::form( "RepoInfo alias (%s) does not match repository alias (%s)",
00212                                               info_r.alias().c_str(), alias().c_str() ) ) );
00213         }
00214         myPool().setRepoInfo( _repo, info_r );
00215         MIL << *this << endl;
00216     }
00217 
00218     void Repository::clearInfo()
00219     {
00220         NO_REPOSITORY_RETURN();
00221         myPool().setRepoInfo( _repo, RepoInfo() );
00222     }
00223 
00224     void Repository::eraseFromPool()
00225     {
00226         NO_REPOSITORY_RETURN();
00227         MIL << *this << " removed from pool" << endl;
00228         myPool()._deleteRepo( _repo );
00229         _id = sat::detail::noRepoId;
00230     }
00231 
00232     Repository Repository::nextInPool() const
00233     {
00234       NO_REPOSITORY_RETURN( noRepository );
00235       for_( it, sat::Pool::instance().reposBegin(), sat::Pool::instance().reposEnd() )
00236       {
00237         if ( *it == *this )
00238         {
00239           if ( ++it != _for_end )
00240             return *it;
00241           break;
00242         }
00243       }
00244       return noRepository;
00245     }
00246 
00247     void Repository::addSolv( const Pathname & file_r )
00248     {
00249       NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo." ) );
00250 
00251       AutoDispose<FILE*> file( ::fopen( file_r.c_str(), "re" ), ::fclose );
00252       if ( file == NULL )
00253       {
00254         file.resetDispose();
00255         ZYPP_THROW( Exception( "Can't open solv-file: "+file_r.asString() ) );
00256       }
00257 
00258       if ( myPool()._addSolv( _repo, file ) != 0 )
00259       {
00260         ZYPP_THROW( Exception( "Error reading solv-file: "+file_r.asString() ) );
00261       }
00262 
00263       MIL << *this << " after adding " << file_r << endl;
00264     }
00265 
00266     void Repository::addHelix( const Pathname & file_r )
00267     {
00268       NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo." ) );
00269 
00270       std::string command( file_r.extension() == ".gz" ? "zcat " : "cat " );
00271       command += file_r.asString();
00272 
00273       AutoDispose<FILE*> file( ::popen( command.c_str(), "re" ), ::pclose );
00274       if ( file == NULL )
00275       {
00276         file.resetDispose();
00277         ZYPP_THROW( Exception( "Can't open helix-file: "+file_r.asString() ) );
00278       }
00279 
00280       if ( myPool()._addHelix( _repo, file ) != 0 )
00281       {
00282         ZYPP_THROW( Exception( "Error reading helix-file: "+file_r.asString() ) );
00283       }
00284 
00285       MIL << *this << " after adding " << file_r << endl;
00286     }
00287 
00288     sat::detail::SolvableIdType Repository::addSolvables( unsigned count_r )
00289     {
00290         NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo.") );
00291         return myPool()._addSolvables( _repo, count_r );
00292     }
00293 
00294     /******************************************************************
00295      **
00296      ** FUNCTION NAME : operator<<
00297      ** FUNCTION TYPE : std::ostream &
00298      */
00299     std::ostream & operator<<( std::ostream & str, const Repository & obj )
00300     {
00301         if ( ! obj )
00302             return str << "noRepository";
00303 
00304         return str << "sat::repo(" << obj.alias() << ")"
00305                    << "{"
00306                    << "prio " << obj.get()->priority << '.' << obj.get()->subpriority
00307                    << ", size " << obj.solvablesSize()
00308                    << "}";
00309     }
00310 
00312     //
00313     // Repository::ProductInfoIterator
00314     //
00316 
00317     Repository::ProductInfoIterator::ProductInfoIterator( sat::SolvAttr attr_r, Repository repo_r )
00318     { base_reference() = sat::LookupRepoAttr( attr_r, repo_r ).begin(); }
00319 
00320     std::string Repository::ProductInfoIterator::label() const
00321     { return base_reference().subFind( sat::SolvAttr::repositoryProductLabel ).asString(); }
00322 
00323     std::string Repository::ProductInfoIterator::cpeId() const
00324     { return base_reference().subFind( sat::SolvAttr::repositoryProductCpeid ).asString(); }
00325 
00327 } // namespace zypp