1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/sat/Repository.cc
15 #include <zypp/base/Logger.h>
16 #include <zypp/base/Gettext.h>
17 #include <zypp/base/Exception.h>
18 #include <zypp/base/Xml.h>
20 #include <zypp/AutoDispose.h>
21 #include <zypp/Pathname.h>
23 #include <zypp/sat/detail/PoolImpl.h>
24 #include <zypp/Repository.h>
25 #include <zypp/ResPool.h>
26 #include <zypp/Product.h>
27 #include <zypp/sat/Pool.h>
31 ///////////////////////////////////////////////////////////////////
33 { /////////////////////////////////////////////////////////////////
35 const Repository Repository::noRepository;
37 const std::string & Repository::systemRepoAlias()
38 { return sat::detail::PoolImpl::systemRepoAlias(); }
40 /////////////////////////////////////////////////////////////////
42 sat::detail::CRepo * Repository::get() const
43 { return myPool().getRepo( _id ); }
45 #define NO_REPOSITORY_RETURN( VAL ) \
46 sat::detail::CRepo * _repo( get() ); \
47 if ( ! _repo ) return VAL
49 #define NO_REPOSITORY_THROW( VAL ) \
50 sat::detail::CRepo * _repo( get() ); \
51 if ( ! _repo ) ZYPP_THROW( VAL )
53 bool Repository::isSystemRepo() const
55 NO_REPOSITORY_RETURN( false );
56 return myPool().isSystemRepo( _repo );
59 std::string Repository::alias() const
61 NO_REPOSITORY_RETURN( std::string() );
67 std::string Repository::name() const
68 { return info().name(); }
70 std::string Repository::label() const
71 { return info().label(); }
73 int Repository::satInternalPriority() const
75 NO_REPOSITORY_RETURN( INT_MIN );
76 return _repo->priority;
79 int Repository::satInternalSubPriority() const
81 NO_REPOSITORY_RETURN( INT_MIN );
82 return _repo->subpriority;
85 Repository::ContentRevision Repository::contentRevision() const
87 NO_REPOSITORY_RETURN( ContentRevision() );
88 sat::LookupRepoAttr q( sat::SolvAttr::repositoryRevision, *this );
89 return q.empty() ? std::string() : q.begin().asString();
92 Repository::ContentIdentifier Repository::contentIdentifier() const
94 NO_REPOSITORY_RETURN( ContentIdentifier() );
95 sat::LookupRepoAttr q( sat::SolvAttr::repositoryRepoid, *this );
96 return q.empty() ? std::string() : q.begin().asString();
99 bool Repository::hasContentIdentifier( const ContentIdentifier & id_r ) const
101 NO_REPOSITORY_RETURN( false );
102 sat::LookupRepoAttr q( sat::SolvAttr::repositoryRepoid, *this );
103 for_( it, q.begin(), q.end() )
104 if ( it.asString() == id_r )
109 zypp::Date Repository::generatedTimestamp() const
111 NO_REPOSITORY_RETURN( 0 );
112 sat::LookupRepoAttr q( sat::SolvAttr::repositoryTimestamp, *this );
113 return( q.empty() ? 0 : q.begin().asUnsigned() );
116 zypp::Date Repository::suggestedExpirationTimestamp() const
118 NO_REPOSITORY_RETURN( 0 );
119 Date generated = generatedTimestamp();
121 return 0; // do not calculate over a missing generated timestamp
123 sat::LookupRepoAttr q( sat::SolvAttr::repositoryExpire, *this );
127 return generated + Date(q.begin().asUnsigned());
130 Repository::Keywords Repository::keywords() const
132 NO_REPOSITORY_RETURN( Keywords() );
133 return Keywords( sat::SolvAttr::repositoryKeywords, *this, sat::LookupAttr::REPO_ATTR );
136 bool Repository::hasKeyword( const std::string & val_r ) const
138 for ( const auto & val : keywords() )
144 bool Repository::maybeOutdated() const
146 NO_REPOSITORY_RETURN( false );
147 // system repo is not mirrored
148 if ( isSystemRepo() )
151 Date suggested = suggestedExpirationTimestamp();
153 // if no data, don't suggest
157 return suggestedExpirationTimestamp() < Date::now();
160 bool Repository::providesUpdatesFor( const CpeId & cpeid_r ) const
162 NO_REPOSITORY_RETURN( false );
164 return false; // filter queries/products without CpeId, as an empty CpeId matches ANYthing.
166 // check in repository metadata
167 for_( it, updatesProductBegin(), updatesProductEnd() )
169 if ( compare( cpeid_r, it.cpeId(), SetRelation::subset ) )
173 // check whether known products refer to this as update repo
174 sat::LookupRepoAttr myIds( sat::SolvAttr::repositoryRepoid, *this ); // usually just one, but...
175 if ( ! myIds.empty() )
177 const ResPool & pool( ResPool::instance() );
178 for_( it, pool.byKindBegin<Product>(), pool.byKindEnd<Product>() )
180 Product::constPtr prod( (*it)->asKind<Product>() );
181 if ( compare( cpeid_r, prod->cpeId(), SetRelation::superset ) )
183 for_( myId, myIds.begin(), myIds.end() )
185 if ( prod->hasUpdateContentIdentifier( myId.asString() ) )
194 bool Repository::isUpdateRepo() const
196 NO_REPOSITORY_RETURN( false );
198 // check in repository metadata
199 if ( updatesProductBegin() != updatesProductEnd() )
202 // check whether known products refer to this as update repo
203 sat::LookupRepoAttr myIds( sat::SolvAttr::repositoryRepoid, *this ); // usually just one, but...
204 if ( ! myIds.empty() )
206 const ResPool & pool( ResPool::instance() );
207 for_( it, pool.byKindBegin<Product>(), pool.byKindEnd<Product>() )
209 for_( myId, myIds.begin(), myIds.end() )
211 if ( (*it)->asKind<Product>()->hasUpdateContentIdentifier( myId.asString() ) )
219 bool Repository::solvablesEmpty() const
221 NO_REPOSITORY_RETURN( true );
222 return !_repo->nsolvables;
225 Repository::size_type Repository::solvablesSize() const
227 NO_REPOSITORY_RETURN( 0 );
228 return _repo->nsolvables;
231 Repository::SolvableIterator Repository::solvablesBegin() const
233 NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
234 sat::detail::SolvableIterator(),
235 sat::detail::SolvableIterator() ) );
236 return make_filter_iterator( detail::ByRepository( *this ),
237 sat::detail::SolvableIterator(_repo->start),
238 sat::detail::SolvableIterator(_repo->end) );
241 Repository::SolvableIterator Repository::solvablesEnd() const
243 NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
244 sat::detail::SolvableIterator(),
245 sat::detail::SolvableIterator() ) );
246 return make_filter_iterator(detail::ByRepository( *this ),
247 sat::detail::SolvableIterator(_repo->end),
248 sat::detail::SolvableIterator(_repo->end) );
251 Repository::ProductInfoIterator Repository::compatibleWithProductBegin() const
253 NO_REPOSITORY_RETURN( ProductInfoIterator() );
254 return ProductInfoIterator( sat::SolvAttr::repositoryDistros, *this );
257 Repository::ProductInfoIterator Repository::compatibleWithProductEnd() const
259 return ProductInfoIterator();
262 Repository::ProductInfoIterator Repository::updatesProductBegin() const
264 NO_REPOSITORY_RETURN( ProductInfoIterator() );
265 return ProductInfoIterator( sat::SolvAttr::repositoryUpdates, *this );
268 Repository::ProductInfoIterator Repository::updatesProductEnd() const
270 return ProductInfoIterator();
273 RepoInfo Repository::info() const
275 NO_REPOSITORY_RETURN( RepoInfo() );
276 return myPool().repoInfo( _repo );
279 void Repository::setInfo( const RepoInfo & info_r )
281 NO_REPOSITORY_THROW( Exception( "Can't set RepoInfo for norepo." ) );
282 if ( info_r.alias() != alias() )
284 ZYPP_THROW( Exception( str::form( "RepoInfo alias (%s) does not match repository alias (%s)",
285 info_r.alias().c_str(), alias().c_str() ) ) );
287 myPool().setRepoInfo( _repo, info_r );
288 MIL << *this << endl;
291 void Repository::clearInfo()
293 NO_REPOSITORY_RETURN();
294 myPool().setRepoInfo( _repo, RepoInfo() );
297 void Repository::eraseFromPool()
299 NO_REPOSITORY_RETURN();
300 MIL << *this << " removed from pool" << endl;
301 myPool()._deleteRepo( _repo );
302 _id = sat::detail::noRepoId;
305 Repository Repository::nextInPool() const
307 NO_REPOSITORY_RETURN( noRepository );
308 for_( it, sat::Pool::instance().reposBegin(), sat::Pool::instance().reposEnd() )
312 if ( ++it != _for_end )
320 void Repository::addSolv( const Pathname & file_r )
322 NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo." ) );
324 AutoDispose<FILE*> file( ::fopen( file_r.c_str(), "re" ), ::fclose );
328 ZYPP_THROW( Exception( "Can't open solv-file: "+file_r.asString() ) );
331 if ( myPool()._addSolv( _repo, file ) != 0 )
333 ZYPP_THROW( Exception( "Error reading solv-file: "+file_r.asString() ) );
336 MIL << *this << " after adding " << file_r << endl;
339 void Repository::addHelix( const Pathname & file_r )
341 NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo." ) );
343 std::string command( file_r.extension() == ".gz" ? "zcat " : "cat " );
344 command += file_r.asString();
346 AutoDispose<FILE*> file( ::popen( command.c_str(), "re" ), ::pclose );
350 ZYPP_THROW( Exception( "Can't open helix-file: "+file_r.asString() ) );
353 if ( myPool()._addHelix( _repo, file ) != 0 )
355 ZYPP_THROW( Exception( "Error reading helix-file: "+file_r.asString() ) );
358 MIL << *this << " after adding " << file_r << endl;
361 void Repository::addTesttags( const Pathname & file_r )
363 NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo." ) );
365 std::string command( file_r.extension() == ".gz" ? "zcat " : "cat " );
366 command += file_r.asString();
368 AutoDispose<FILE*> file( ::popen( command.c_str(), "re" ), ::pclose );
372 ZYPP_THROW( Exception( "Can't open testtags-file: "+file_r.asString() ) );
375 if ( myPool()._addTesttags( _repo, file ) != 0 )
377 ZYPP_THROW( Exception( "Error reading testtags-file: "+file_r.asString() ) );
380 MIL << *this << " after adding " << file_r << endl;
383 sat::detail::SolvableIdType Repository::addSolvables( unsigned count_r )
385 NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo.") );
386 return myPool()._addSolvables( _repo, count_r );
389 /******************************************************************
391 ** FUNCTION NAME : operator<<
392 ** FUNCTION TYPE : std::ostream &
394 std::ostream & operator<<( std::ostream & str, const Repository & obj )
397 return str << "noRepository";
399 return str << "sat::repo(" << obj.alias() << ")"
401 << "prio " << obj.get()->priority << '.' << obj.get()->subpriority
402 << ", size " << obj.solvablesSize()
406 std::ostream & dumpAsXmlOn( std::ostream & str, const Repository & obj )
408 return xmlout::node( str, "repository", {
409 { "name", obj.name() },
410 { "alias", obj.alias() }
414 //////////////////////////////////////////////////////////////////
417 void RepositoryIterator::increment()
421 sat::detail::CPool * satpool = sat::Pool::instance().get();
424 } while ( base() < satpool->repos+satpool->nrepos && !*base() );
427 } // namespace detail
428 //////////////////////////////////////////////////////////////////
430 ///////////////////////////////////////////////////////////////////
432 // Repository::ProductInfoIterator
434 ///////////////////////////////////////////////////////////////////
436 Repository::ProductInfoIterator::ProductInfoIterator( sat::SolvAttr attr_r, Repository repo_r )
437 { base_reference() = sat::LookupRepoAttr( attr_r, repo_r ).begin(); }
439 std::string Repository::ProductInfoIterator::label() const
440 { return base_reference().subFind( sat::SolvAttr::repositoryProductLabel ).asString(); }
442 CpeId Repository::ProductInfoIterator::cpeId() const
443 { return CpeId( base_reference().subFind( sat::SolvAttr::repositoryProductCpeid ).asString(), CpeId::noThrow ); }
445 /////////////////////////////////////////////////////////////////
447 ///////////////////////////////////////////////////////////////////