1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/Repository.h
12 #ifndef ZYPP_SAT_REPOSITORY_H
13 #define ZYPP_SAT_REPOSITORY_H
16 #include "zypp/base/Iterator.h"
17 #include "zypp/Pathname.h"
18 #include "zypp/sat/detail/PoolMember.h"
19 #include "zypp/sat/LookupAttr.h" // LookupAttrTools.h included at EOF
20 #include "zypp/sat/Solvable.h"
21 #include "zypp/RepoInfo.h"
22 #include "zypp/Date.h"
23 #include "zypp/CpeId.h"
25 ///////////////////////////////////////////////////////////////////
27 { /////////////////////////////////////////////////////////////////
34 ///////////////////////////////////////////////////////////////////
36 // CLASS NAME : Repository
39 class Repository : protected sat::detail::PoolMember
42 typedef filter_iterator<detail::ByRepository, sat::detail::SolvableIterator> SolvableIterator;
43 typedef sat::detail::size_type size_type;
44 typedef sat::detail::RepoIdType IdType;
46 typedef sat::ArrayAttr<std::string,std::string> Keywords;
48 typedef std::string ContentRevision;
49 typedef std::string ContentIdentifier;
52 /** Default ctor creates \ref noRepository.*/
54 : _id( sat::detail::noRepoId ) {}
56 /** \ref PoolImpl ctor. */
57 explicit Repository( IdType id_r )
61 /** Represents no \ref Repository. */
62 static const Repository noRepository;
64 /** Evaluate \ref Repository in a boolean context (\c != \c noRepository). */
65 explicit operator bool() const
66 { return get() != nullptr; }
68 /** Reserved system repository alias \c @System. */
69 static const std::string & systemRepoAlias();
71 /** Return whether this is the system repository. */
72 bool isSystemRepo() const;
76 * Short unique string to identify a repo.
79 * If you are looking for a label to display
81 * ie: "openSUSE 10.3 Main repository"
84 std::string alias() const;
86 /** Label to display for this repo. */
87 std::string name() const;
89 /** Alias or name, according to \ref ZConfig::repoLabelIsAlias */
90 std::string label() const;
92 /** User string: \ref label (alias or name) */
93 std::string asUserString() const
97 /** Timestamp or arbitrary user supplied string.
98 * \c /repomd/revision/text() in \c repomd.xml.
100 ContentRevision contentRevision() const;
102 /** Unique string identifying a repositories content.
103 * \c /repomd/tags/repo/text() in \c repomd.xml.
107 * <repo>obsrepository://build.suse.de/SUSE:Factory:Head:Internal/standard</repo>
109 * Semantically the value is just a plain string, even
110 * if OBS often uses the location of the project as
113 ContentIdentifier contentIdentifier() const;
115 /** Whether \a id_r matches this repos content identifier. */
116 bool hasContentIdentifier( const ContentIdentifier & id_r ) const;
119 * Timestamp when this repository was generated
121 * Usually this value is calculated as the newer
122 * timestamp from the timestamp of all the resources
123 * that conform the repository's metadata.
125 * For example in a rpm-md repository, it would be
126 * the resource specified in the xml file whith
127 * the newest timestamp attribute (which is the
128 * timestamp of the file in the server ).
130 * The timestamp is 0 if the repository does not
131 * specify when it was generated.
134 Date generatedTimestamp() const;
137 * Suggested expiration timestamp.
139 * Repositories can define an amount of time
140 * they expire, with the generated timestamp as
141 * the base point of time.
143 * Note that is the responsability of the repository
144 * to freshen the generated timestamp to tell the
145 * client that the repo is alive and updating the
148 * The timestamp is 0 if the repository does not specify
149 * an expiration date.
152 Date suggestedExpirationTimestamp() const;
155 * repository keywords (tags)
157 Keywords keywords() const;
159 /** Whether \a val_r is present in keywords. */
160 bool hasKeyword( const std::string & val_r ) const;
163 * The suggested expiration date of this repository
166 * rpm-md repositories can provide this tag using the
167 * expire extension tag:
168 * \see http://en.opensuse.org/Standards/Rpm_Metadata#SUSE_repository_info_.28suseinfo.xml.29.2C_extensions_to_repomd.xml
170 bool maybeOutdated() const;
172 /** Hint whether the Repo may provide updates for a product.
174 * Either the repository claims to update a product via a repository updates
175 * tag in it's metadata or a known product lists the repositories ContentIdentifier
176 * as required update repo.
178 bool isUpdateRepo() const;
180 /** Hint whether the Repo may provide updates for a product identified by it's \ref CpeId
182 * Either the repository claims to update a product via a repository updates
183 * tag in it's metadata or a known product lists the repositories ContentIdentifier
184 * as required update repo.
186 bool providesUpdatesFor( const CpeId & cpeid_r ) const;
188 /** Whether \ref Repository contains solvables. */
189 bool solvablesEmpty() const;
191 /** Number of solvables in \ref Repository. */
192 size_type solvablesSize() const;
194 /** Iterator to the first \ref Solvable. */
195 SolvableIterator solvablesBegin() const;
197 /** Iterator behind the last \ref Solvable. */
198 SolvableIterator solvablesEnd() const;
200 /** Iterate the repositories Solvables. */
201 Iterable<SolvableIterator> solvables() const;
205 /** Query class for Repository related products */
206 class ProductInfoIterator;
209 * Get an iterator to the beginning of the repository
210 * compatible distros.
211 * \note This is only a hint. There is no guarantee that
212 * the repository is built for that product.
213 * \see Repository::ProductInfoIterator
215 ProductInfoIterator compatibleWithProductBegin() const;
218 * Get an iterator to the end of the repository
219 * compatible distros.
220 * \see Repository::ProductInfoIterator
222 ProductInfoIterator compatibleWithProductEnd() const;
224 /** Iterate the repository compatible distros. */
225 Iterable<ProductInfoIterator> compatibleWithProduct() const;
229 * Get an iterator to the beginning of distos the repository
230 * provides upadates for.
231 * \note This is only a hint within the repositories metadata.
232 * The same realation might be expressed by a product listing
233 * this repositories ContentIdentifier as required update repo.
234 * \see Repository::ProductInfoIterator
236 ProductInfoIterator updatesProductBegin() const;
239 * Get an iterator to the end of distos the repository
240 * provides upadates for.
241 * \see Repository::ProductInfoIterator
243 ProductInfoIterator updatesProductEnd() const;
245 /** Iterate distos the repository provides upadates for. */
246 Iterable<ProductInfoIterator> updatesProduct() const;
249 /** Return any associated \ref RepoInfo. */
250 RepoInfo info() const;
252 /** Set \ref RepoInfo for this repository.
253 * \throws Exception if this is \ref noRepository
254 * \throws Exception if the \ref RepoInfo::alias
255 * does not match the \ref Repository::name.
257 void setInfo( const RepoInfo & info_r );
259 /** Remove any \ref RepoInfo set for this repository. */
263 /** Remove this \ref Repository from it's \ref Pool. */
264 void eraseFromPool();
266 /** Functor calling \ref eraseFromPool. */
267 struct EraseFromPool;
270 /** Return next Repository in \ref Pool (or \ref noRepository). */
271 Repository nextInPool() const;
274 /** \name Repository content manipulating methods.
275 * \todo maybe a separate Repository/Solvable content manip interface
276 * provided by the pool.
279 /** Load \ref Solvables from a solv-file.
280 * In case of an exception the repository remains in the \ref Pool.
281 * \throws Exception if this is \ref noRepository
282 * \throws Exception if loading the solv-file fails.
283 * \see \ref Pool::addRepoSolv and \ref Repository::EraseFromPool
285 void addSolv( const Pathname & file_r );
287 /** Load \ref Solvables from a helix-file.
288 * Supports loading of gzip compressed files (.gz). In case of an exception
289 * the repository remains in the \ref Pool.
290 * \throws Exception if this is \ref noRepository
291 * \throws Exception if loading the helix-file fails.
292 * \see \ref Pool::addRepoHelix and \ref Repository::EraseFromPool
294 void addHelix( const Pathname & file_r );
296 /** Add \c count_r new empty \ref Solvable to this \ref Repository. */
297 sat::Solvable::IdType addSolvables( unsigned count_r );
298 /** \overload Add only one new \ref Solvable. */
299 sat::Solvable::IdType addSolvable()
300 { return addSolvables( 1 ); }
304 /** Expert backdoor. */
305 sat::detail::CRepo * get() const;
306 /** Expert backdoor. */
307 IdType id() const { return _id; }
308 /** libsolv internal priorities.
309 * Unlike the \ref RepoInfo priority which tries to be YUM conform
310 * (H[1-99]L), this one is the solvers internal priority representation.
311 * It is type \c int and as one might expect it, the higher the value
312 * the higher the priority. Subpriority is currently used to express
313 * media preferences (\see \ref MediaPriority).
316 int satInternalPriority() const;
317 int satInternalSubPriority() const;
323 ///////////////////////////////////////////////////////////////////
325 /** \relates Repository Stream output */
326 std::ostream & operator<<( std::ostream & str, const Repository & obj );
328 /** \relates Repository XML output */
329 std::ostream & dumpAsXmlOn( std::ostream & str, const Repository & obj );
331 /** \relates Repository */
332 inline bool operator==( const Repository & lhs, const Repository & rhs )
333 { return lhs.get() == rhs.get(); }
335 /** \relates Repository */
336 inline bool operator!=( const Repository & lhs, const Repository & rhs )
337 { return lhs.get() != rhs.get(); }
339 /** \relates Repository */
340 inline bool operator<( const Repository & lhs, const Repository & rhs )
341 { return lhs.get() < rhs.get(); }
343 ///////////////////////////////////////////////////////////////////
345 * Query class for Repository related products
347 * Products are identified by CpeIds within the repositories metadata.
348 * \see http://en.opensuse.org/Standards/Rpm_Metadata#SUSE_repository_info_.28suseinfo.xml.29.2C_extensions_to_repomd.xml
350 * The iterator does not provide a dereference
351 * operator so you can do * on it, but you can
352 * access the attributes of each related product
353 * directly from the iterator.
356 * for_( it, repo.compatibleWithProductBegin(), repo.compatibleWithProductEnd() )
358 * cout << it.label() << ": " << it.cpeid() << endl;
363 class Repository::ProductInfoIterator : public boost::iterator_adaptor<
364 Repository::ProductInfoIterator // Derived
365 , sat::LookupAttr::iterator // Base
367 , boost::forward_traversal_tag // CategoryOrTraversal
372 ProductInfoIterator()
376 std::string label() const;
378 /** The Common Platform Enumeration name for this product. */
382 friend class Repository;
383 /** Hide ctor as just a limited set of attributes is valid. */
384 explicit ProductInfoIterator( sat::SolvAttr attr_r, Repository repo_r );
387 friend class boost::iterator_core_access;
388 int dereference() const { return 0; }
390 ///////////////////////////////////////////////////////////////////
392 /** Iterate the repository compatible distros. */
393 inline Iterable<Repository::ProductInfoIterator> Repository::compatibleWithProduct() const
394 { return makeIterable( compatibleWithProductBegin(), compatibleWithProductEnd() ); }
396 /** Iterate distos the repository provides upadates for. */
397 inline Iterable<Repository::ProductInfoIterator> Repository::updatesProduct() const
398 { return makeIterable( updatesProductBegin(), updatesProductEnd() ); }
400 ///////////////////////////////////////////////////////////////////
402 // CLASS NAME : Repository::EraseFromPool
404 /** Functor removing \ref Repository from it's \ref Pool.
406 * E.g. used as dispose function in. \ref AutoDispose
407 * to provide a convenient and exception safe temporary
411 * MIL << "1 " << satpool << endl;
413 * AutoDispose<Repository> tmprepo( (Repository::EraseFromPool()) );
414 * *tmprepo = satpool.reposInsert( "A" );
415 * tmprepo->addSolv( "sl10.1-beta7-packages.solv" );
416 * DBG << "2 " << satpool << endl;
417 * // Calling 'tmprepo.resetDispose();' here
418 * // would keep the Repo.
420 * MIL << "3 " << satpool << endl;
423 * 1 sat::pool(){0repos|2slov}
424 * 2 sat::pool(){1repos|2612slov}
425 * 3 sat::pool(){0repos|2slov}
427 * Leaving the block without calling <tt>tmprepo.resetDispose();</tt>
428 * before, will automatically remove the \ref Repo from it's \ref Pool.
430 struct Repository::EraseFromPool
432 void operator()( Repository repository_r ) const
433 { repository_r.eraseFromPool(); }
435 ///////////////////////////////////////////////////////////////////
437 ///////////////////////////////////////////////////////////////////
439 { /////////////////////////////////////////////////////////////////
440 ///////////////////////////////////////////////////////////////////
442 // CLASS NAME : RepositoryIterator
445 class RepositoryIterator : public boost::iterator_adaptor<
446 RepositoryIterator // Derived
447 , sat::detail::CRepo ** // Base
448 , Repository // Value
449 , boost::forward_traversal_tag // CategoryOrTraversal
450 , Repository // Reference
455 : RepositoryIterator::iterator_adaptor_( 0 )
458 explicit RepositoryIterator( sat::detail::CRepo ** p )
459 : RepositoryIterator::iterator_adaptor_( p )
463 friend class boost::iterator_core_access;
465 Repository dereference() const
466 { return Repository( *base() ); }
470 ///////////////////////////////////////////////////////////////////
471 ///////////////////////////////////////////////////////////////////
473 // CLASS NAME : ByRepository
475 /** Functor filtering \ref Solvable by \ref Repository.*/
479 ByRepository( const Repository & repository_r ) : _repository( repository_r ) {}
480 ByRepository( sat::detail::RepoIdType id_r ) : _repository( id_r ) {}
483 bool operator()( const sat::Solvable & slv_r ) const
484 { return slv_r.repository() == _repository; }
487 Repository _repository;
489 ///////////////////////////////////////////////////////////////////
490 /////////////////////////////////////////////////////////////////
491 } // namespace detail
492 ///////////////////////////////////////////////////////////////////
494 inline Iterable<Repository::SolvableIterator> Repository::solvables() const
495 { return makeIterable( solvablesBegin(), solvablesEnd() ); }
497 /////////////////////////////////////////////////////////////////
499 ///////////////////////////////////////////////////////////////////
501 // Late include as sat::ArrayAttr requires Repository.h
502 #include "zypp/sat/LookupAttrTools.h"
504 #endif // ZYPP_SAT_REPOSITORY_H