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 /** Load \ref Solvables from a libsolv testtags-file.
297 * Supports loading of gzip compressed files (.gz). In case of an exception
298 * the repository remains in the \ref Pool.
299 * \throws Exception if this is \ref noRepository
300 * \throws Exception if loading the helix-file fails.
301 * \see \ref Pool::addRepoTesttags and \ref Repository::EraseFromPool
303 void addTesttags(const Pathname &file_r);
305 /** Add \c count_r new empty \ref Solvable to this \ref Repository. */
306 sat::Solvable::IdType addSolvables( unsigned count_r );
307 /** \overload Add only one new \ref Solvable. */
308 sat::Solvable::IdType addSolvable()
309 { return addSolvables( 1 ); }
313 /** Expert backdoor. */
314 sat::detail::CRepo * get() const;
315 /** Expert backdoor. */
316 IdType id() const { return _id; }
317 /** libsolv internal priorities.
318 * Unlike the \ref RepoInfo priority which tries to be YUM conform
319 * (H[1-99]L), this one is the solvers internal priority representation.
320 * It is type \c int and as one might expect it, the higher the value
321 * the higher the priority. Subpriority is currently used to express
322 * media preferences (\see \ref MediaPriority).
325 int satInternalPriority() const;
326 int satInternalSubPriority() const;
331 ///////////////////////////////////////////////////////////////////
333 /** \relates Repository Stream output */
334 std::ostream & operator<<( std::ostream & str, const Repository & obj );
336 /** \relates Repository XML output */
337 std::ostream & dumpAsXmlOn( std::ostream & str, const Repository & obj );
339 /** \relates Repository */
340 inline bool operator==( const Repository & lhs, const Repository & rhs )
341 { return lhs.get() == rhs.get(); }
343 /** \relates Repository */
344 inline bool operator!=( const Repository & lhs, const Repository & rhs )
345 { return lhs.get() != rhs.get(); }
347 /** \relates Repository */
348 inline bool operator<( const Repository & lhs, const Repository & rhs )
349 { return lhs.get() < rhs.get(); }
351 ///////////////////////////////////////////////////////////////////
353 * Query class for Repository related products
355 * Products are identified by CpeIds within the repositories metadata.
356 * \see http://en.opensuse.org/Standards/Rpm_Metadata#SUSE_repository_info_.28suseinfo.xml.29.2C_extensions_to_repomd.xml
358 * The iterator does not provide a dereference
359 * operator so you can do * on it, but you can
360 * access the attributes of each related product
361 * directly from the iterator.
364 * for_( it, repo.compatibleWithProductBegin(), repo.compatibleWithProductEnd() )
366 * cout << it.label() << ": " << it.cpeid() << endl;
371 class Repository::ProductInfoIterator : public boost::iterator_adaptor<
372 Repository::ProductInfoIterator // Derived
373 , sat::LookupAttr::iterator // Base
375 , boost::forward_traversal_tag // CategoryOrTraversal
380 ProductInfoIterator()
384 std::string label() const;
386 /** The Common Platform Enumeration name for this product. */
390 friend class Repository;
391 /** Hide ctor as just a limited set of attributes is valid. */
392 explicit ProductInfoIterator( sat::SolvAttr attr_r, Repository repo_r );
395 friend class boost::iterator_core_access;
396 int dereference() const { return 0; }
398 ///////////////////////////////////////////////////////////////////
400 /** Iterate the repository compatible distros. */
401 inline Iterable<Repository::ProductInfoIterator> Repository::compatibleWithProduct() const
402 { return makeIterable( compatibleWithProductBegin(), compatibleWithProductEnd() ); }
404 /** Iterate distos the repository provides upadates for. */
405 inline Iterable<Repository::ProductInfoIterator> Repository::updatesProduct() const
406 { return makeIterable( updatesProductBegin(), updatesProductEnd() ); }
408 ///////////////////////////////////////////////////////////////////
410 // CLASS NAME : Repository::EraseFromPool
412 /** Functor removing \ref Repository from it's \ref Pool.
414 * E.g. used as dispose function in. \ref AutoDispose
415 * to provide a convenient and exception safe temporary
419 * MIL << "1 " << satpool << endl;
421 * AutoDispose<Repository> tmprepo( (Repository::EraseFromPool()) );
422 * *tmprepo = satpool.reposInsert( "A" );
423 * tmprepo->addSolv( "sl10.1-beta7-packages.solv" );
424 * DBG << "2 " << satpool << endl;
425 * // Calling 'tmprepo.resetDispose();' here
426 * // would keep the Repo.
428 * MIL << "3 " << satpool << endl;
431 * 1 sat::pool(){0repos|2solv}
432 * 2 sat::pool(){1repos|2612solv}
433 * 3 sat::pool(){0repos|2solv}
435 * Leaving the block without calling <tt>tmprepo.resetDispose();</tt>
436 * before, will automatically remove the \ref Repo from it's \ref Pool.
438 struct Repository::EraseFromPool
440 void operator()( Repository repository_r ) const
441 { repository_r.eraseFromPool(); }
443 ///////////////////////////////////////////////////////////////////
445 ///////////////////////////////////////////////////////////////////
447 { /////////////////////////////////////////////////////////////////
448 ///////////////////////////////////////////////////////////////////
450 // CLASS NAME : RepositoryIterator
453 class RepositoryIterator : public boost::iterator_adaptor<
454 RepositoryIterator // Derived
455 , sat::detail::CRepo ** // Base
456 , Repository // Value
457 , boost::forward_traversal_tag // CategoryOrTraversal
458 , Repository // Reference
463 : RepositoryIterator::iterator_adaptor_( 0 )
466 explicit RepositoryIterator( sat::detail::CRepo ** p )
467 : RepositoryIterator::iterator_adaptor_( p )
471 friend class boost::iterator_core_access;
473 Repository dereference() const
474 { return Repository( *base() ); }
478 ///////////////////////////////////////////////////////////////////
479 ///////////////////////////////////////////////////////////////////
481 // CLASS NAME : ByRepository
483 /** Functor filtering \ref Solvable by \ref Repository.*/
487 ByRepository( const Repository & repository_r ) : _repository( repository_r ) {}
488 ByRepository( sat::detail::RepoIdType id_r ) : _repository( id_r ) {}
491 bool operator()( const sat::Solvable & slv_r ) const
492 { return slv_r.repository() == _repository; }
495 Repository _repository;
497 ///////////////////////////////////////////////////////////////////
498 /////////////////////////////////////////////////////////////////
499 } // namespace detail
500 ///////////////////////////////////////////////////////////////////
502 inline Iterable<Repository::SolvableIterator> Repository::solvables() const
503 { return makeIterable( solvablesBegin(), solvablesEnd() ); }
505 /////////////////////////////////////////////////////////////////
507 ///////////////////////////////////////////////////////////////////
509 // Late include as sat::ArrayAttr requires Repository.h
510 #include <zypp/sat/LookupAttrTools.h>
512 #endif // ZYPP_SAT_REPOSITORY_H