Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / Repository.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/Repository.h
10  *
11 */
12 #ifndef ZYPP_SAT_REPOSITORY_H
13 #define ZYPP_SAT_REPOSITORY_H
14
15 #include <iosfwd>
16 #include "zypp/Pathname.h"
17 #include "zypp/sat/detail/PoolMember.h"
18 #include "zypp/sat/LookupAttr.h"     // LookupAttrTools.h included at EOF
19 #include "zypp/sat/Solvable.h"
20 #include "zypp/RepoInfo.h"
21 #include "zypp/Date.h"
22 #include "zypp/CpeId.h"
23
24 ///////////////////////////////////////////////////////////////////
25 namespace zypp
26 { /////////////////////////////////////////////////////////////////
27
28     namespace detail
29     {
30       struct ByRepository;
31     }
32
33     ///////////////////////////////////////////////////////////////////
34     //
35     //  CLASS NAME : Repository
36     //
37     /** */
38     class Repository : protected sat::detail::PoolMember
39     {
40     public:
41         typedef filter_iterator<detail::ByRepository, sat::detail::SolvableIterator> SolvableIterator;
42         typedef sat::detail::size_type size_type;
43         typedef sat::detail::RepoIdType IdType;
44
45         typedef sat::ArrayAttr<std::string,std::string> Keywords;
46
47         typedef std::string ContentRevision;
48         typedef std::string ContentIdentifier;
49
50     public:
51         /** Default ctor creates \ref noRepository.*/
52         Repository()
53         : _id( sat::detail::noRepoId ) {}
54
55         /** \ref PoolImpl ctor. */
56         explicit Repository( IdType id_r )
57         : _id( id_r ) {}
58
59     public:
60         /** Represents no \ref Repository. */
61         static const Repository noRepository;
62
63         /** Evaluate \ref Repository in a boolean context (\c != \c noRepository). */
64         explicit operator bool() const
65         { return get() != nullptr; }
66
67         /** Reserved system repository alias \c @System. */
68         static const std::string & systemRepoAlias();
69
70         /** Return whether this is the system repository. */
71         bool isSystemRepo() const;
72
73     public:
74          /**
75           * Short unique string to identify a repo.
76           * ie: openSUSE-10.3
77           *
78           * If you are looking for a label to display
79           * see \ref name().
80           * ie: "openSUSE 10.3 Main repository"
81           *
82           */
83         std::string alias() const;
84
85         /** Label to display for this repo. */
86         std::string name() const;
87
88         /** Alias or name, according to \ref ZConfig::repoLabelIsAlias */
89         std::string label() const;
90
91         /** User string: \ref label (alias or name) */
92         std::string asUserString() const
93         { return label(); }
94
95     public:
96         /** Timestamp or arbitrary user supplied string.
97          * \c /repomd/revision/text() in \c repomd.xml.
98          */
99         ContentRevision contentRevision() const;
100
101         /** Unique string identifying a repositories content.
102          * \c /repomd/tags/repo/text() in \c repomd.xml.
103          * \code
104          * <repomd ....>
105          *  <tags>
106          *   <repo>obsrepository://build.suse.de/SUSE:Factory:Head:Internal/standard</repo>
107          * \endcode
108          * Semantically the value is just a plain string, even
109          * if OBS often uses the location of the project as
110          * unique identifyer.
111          */
112         ContentIdentifier contentIdentifier() const;
113
114         /** Whether \a id_r matches this repos content identifier. */
115         bool hasContentIdentifier( const ContentIdentifier & id_r ) const;
116
117         /**
118          * Timestamp when this repository was generated
119          *
120          * Usually this value is calculated as the newer
121          * timestamp from the timestamp of all the resources
122          * that conform the repository's metadata.
123          *
124          * For example in a rpm-md repository, it would be
125          * the resource specified in the xml file whith
126          * the newest timestamp attribute (which is the
127          * timestamp of the file in the server ).
128          *
129          * The timestamp is 0 if the repository does not
130          * specify when it was generated.
131          *
132          */
133         Date generatedTimestamp() const;
134
135         /**
136          * Suggested expiration timestamp.
137          *
138          * Repositories can define an amount of time
139          * they expire, with the generated timestamp as
140          * the base point of time.
141          *
142          * Note that is the responsability of the repository
143          * to freshen the generated timestamp to tell the
144          * client that the repo is alive and updating the
145          * metadata.
146          *
147          * The timestamp is 0 if the repository does not specify
148          * an expiration date.
149          *
150          */
151         Date suggestedExpirationTimestamp() const;
152
153         /**
154          * repository keywords (tags)
155          */
156         Keywords keywords() const;
157
158         /** Whether \a val_r is present in keywords. */
159         bool hasKeyword( const std::string & val_r ) const;
160
161         /**
162          * The suggested expiration date of this repository
163          * already passed
164          *
165          * rpm-md repositories can provide this tag using the
166          * expire extension tag:
167          * \see http://en.opensuse.org/Standards/Rpm_Metadata#SUSE_repository_info_.28suseinfo.xml.29.2C_extensions_to_repomd.xml
168          */
169         bool maybeOutdated() const;
170
171         /** Hint whether the Repo may provide updates for a product.
172          *
173          * Either the repository claims to update a product via a repository updates
174          * tag in it's metadata or a known product lists the repositories ContentIdentifier
175          * as required update repo.
176          */
177         bool isUpdateRepo() const;
178
179         /** Hint whether the Repo may provide updates for a product identified by it's \ref CpeId
180          *
181          * Either the repository claims to update a product via a repository updates
182          * tag in it's metadata or a known product lists the repositories ContentIdentifier
183          * as required update repo.
184          */
185         bool providesUpdatesFor( const CpeId & cpeid_r ) const;
186
187         /** Whether \ref Repository contains solvables. */
188         bool solvablesEmpty() const;
189
190         /** Number of solvables in \ref Repository. */
191         size_type solvablesSize() const;
192
193         /** Iterator to the first \ref Solvable. */
194         SolvableIterator solvablesBegin() const;
195
196         /** Iterator behind the last \ref Solvable. */
197         SolvableIterator solvablesEnd() const;
198
199     public:
200
201       /** Query class for Repository related products */
202       class ProductInfoIterator;
203
204       /**
205        * Get an iterator to the beginning of the repository
206        * compatible distros.
207        * \note This is only a hint. There is no guarantee that
208        * the repository is built for that product.
209        * \see Repository::ProductInfoIterator
210        */
211       ProductInfoIterator compatibleWithProductBegin() const;
212
213       /**
214        * Get an iterator to the end of the repository
215        * compatible distros.
216        * \see Repository::ProductInfoIterator
217        */
218       ProductInfoIterator compatibleWithProductEnd() const;
219
220       /**
221        * Get an iterator to the beginning of distos the repository
222        * provides upadates for.
223        * \note This is only a hint within the repositories metadata.
224        * The same realation might be expressed by a product listing
225        * this repositories ContentIdentifier as required update repo.
226        * \see Repository::ProductInfoIterator
227        */
228       ProductInfoIterator updatesProductBegin() const;
229
230       /**
231        * Get an iterator to the end of distos the repository
232        * provides upadates for.
233        * \see Repository::ProductInfoIterator
234        */
235       ProductInfoIterator updatesProductEnd() const;
236
237     public:
238         /** Return any associated \ref RepoInfo. */
239         RepoInfo info() const;
240
241         /** Set \ref RepoInfo for this repository.
242          * \throws Exception if this is \ref noRepository
243          * \throws Exception if the \ref RepoInfo::alias
244          *         does not match the \ref Repository::name.
245          */
246         void setInfo( const RepoInfo & info_r );
247
248         /** Remove any \ref RepoInfo set for this repository. */
249         void clearInfo();
250
251     public:
252         /** Remove this \ref Repository from it's \ref Pool. */
253         void eraseFromPool();
254
255         /** Functor calling \ref eraseFromPool. */
256         struct EraseFromPool;
257
258    public:
259         /** Return next Repository in \ref Pool (or \ref noRepository). */
260         Repository nextInPool() const;
261
262    public:
263         /** \name Repository content manipulating methods.
264          * \todo maybe a separate Repository/Solvable content manip interface
265          * provided by the pool.
266          */
267         //@{
268         /** Load \ref Solvables from a solv-file.
269          * In case of an exception the repository remains in the \ref Pool.
270          * \throws Exception if this is \ref noRepository
271          * \throws Exception if loading the solv-file fails.
272          * \see \ref Pool::addRepoSolv and \ref Repository::EraseFromPool
273          */
274         void addSolv( const Pathname & file_r );
275
276          /** Load \ref Solvables from a helix-file.
277          * Supports loading of gzip compressed files (.gz). In case of an exception
278          * the repository remains in the \ref Pool.
279          * \throws Exception if this is \ref noRepository
280          * \throws Exception if loading the helix-file fails.
281          * \see \ref Pool::addRepoHelix and \ref Repository::EraseFromPool
282          */
283         void addHelix( const Pathname & file_r );
284
285        /** Add \c count_r new empty \ref Solvable to this \ref Repository. */
286         sat::Solvable::IdType addSolvables( unsigned count_r );
287         /** \overload Add only one new \ref Solvable. */
288         sat::Solvable::IdType addSolvable()
289             { return addSolvables( 1 ); }
290         //@}
291
292     public:
293         /** Expert backdoor. */
294         ::_Repo * get() const;
295         /** Expert backdoor. */
296         IdType id() const { return _id; }
297         /** libsolv internal priorities.
298          * Unlike the \ref RepoInfo priority which tries to be YUM conform
299          * (H[1-99]L), this one is the solvers internal priority representation.
300          * It is type \c int and as one might expect it, the higher the value
301          * the higher the priority. Subpriority is currently used to express
302          * media preferences (\see \ref MediaPriority).
303          */
304         //@{
305         int satInternalPriority() const;
306         int satInternalSubPriority() const;
307         //@}
308
309     private:
310         IdType _id;
311     };
312     ///////////////////////////////////////////////////////////////////
313
314     /** \relates Repository Stream output */
315     std::ostream & operator<<( std::ostream & str, const Repository & obj );
316
317     /** \relates Repository XML output */
318     std::ostream & dumpAsXmlOn( std::ostream & str, const Repository & obj );
319
320     /** \relates Repository */
321     inline bool operator==( const Repository & lhs, const Repository & rhs )
322     { return lhs.get() == rhs.get(); }
323
324     /** \relates Repository */
325     inline bool operator!=( const Repository & lhs, const Repository & rhs )
326     { return lhs.get() != rhs.get(); }
327
328     /** \relates Repository */
329     inline bool operator<( const Repository & lhs, const Repository & rhs )
330     { return lhs.get() < rhs.get(); }
331
332     ///////////////////////////////////////////////////////////////////
333     /**
334      * Query class for Repository related products
335      *
336      * Products are identified by CpeIds within the repositories metadata.
337      * \see http://en.opensuse.org/Standards/Rpm_Metadata#SUSE_repository_info_.28suseinfo.xml.29.2C_extensions_to_repomd.xml
338      *
339      * The iterator does not provide a dereference
340      * operator so you can do * on it, but you can
341      * access the attributes of each related product
342      * directly from the iterator.
343      *
344      * \code
345      * for_( it, repo.compatibleWithProductBegin(), repo.compatibleWithProductEnd() )
346      * {
347      *   cout << it.label() << ": " << it.cpeid() << endl;
348      * }
349      * \endcode
350      *
351      */
352     class Repository::ProductInfoIterator : public boost::iterator_adaptor<
353         Repository::ProductInfoIterator    // Derived
354         , sat::LookupAttr::iterator        // Base
355         , int                              // Value
356         , boost::forward_traversal_tag     // CategoryOrTraversal
357         , int                              // Reference
358     >
359     {
360       public:
361         ProductInfoIterator()
362         {}
363
364         /** Product label */
365         std::string label() const;
366
367         /** The Common Platform Enumeration name for this product. */
368         CpeId cpeId() const;
369
370       private:
371         friend class Repository;
372         /** Hide ctor as just a limited set of attributes is valid. */
373         explicit ProductInfoIterator( sat::SolvAttr attr_r, Repository repo_r );
374
375       private:
376         friend class boost::iterator_core_access;
377         int dereference() const { return 0; }
378     };
379     ///////////////////////////////////////////////////////////////////
380
381     ///////////////////////////////////////////////////////////////////
382     //
383     //  CLASS NAME : Repository::EraseFromPool
384     //
385     /** Functor removing \ref Repository from it's \ref Pool.
386      *
387      * E.g. used as dispose function in. \ref AutoDispose
388      * to provide a convenient and exception safe temporary
389      * \ref Repository.
390      * \code
391      *  sat::Pool satpool;
392      *  MIL << "1 " << satpool << endl;
393      *  {
394      *    AutoDispose<Repository> tmprepo( (Repository::EraseFromPool()) );
395      *    *tmprepo = satpool.reposInsert( "A" );
396      *    tmprepo->addSolv( "sl10.1-beta7-packages.solv" );
397      *    DBG << "2 " << satpool << endl;
398      *    // Calling 'tmprepo.resetDispose();' here
399      *    // would keep the Repo.
400      *  }
401      *  MIL << "3 " << satpool << endl;
402      * \endcode
403      * \code
404      * 1 sat::pool(){0repos|2slov}
405      * 2 sat::pool(){1repos|2612slov}
406      * 3 sat::pool(){0repos|2slov}
407      * \endcode
408      * Leaving the block without calling <tt>tmprepo.resetDispose();</tt>
409      * before, will automatically remove the \ref Repo from it's \ref Pool.
410      */
411     struct Repository::EraseFromPool
412     {
413         void operator()( Repository repository_r ) const
414             { repository_r.eraseFromPool(); }
415     };
416     ///////////////////////////////////////////////////////////////////
417
418     ///////////////////////////////////////////////////////////////////
419     namespace detail
420     { /////////////////////////////////////////////////////////////////
421       ///////////////////////////////////////////////////////////////////
422       //
423       //        CLASS NAME : RepositoryIterator
424       //
425       /** */
426       class RepositoryIterator : public boost::iterator_adaptor<
427             RepositoryIterator                            // Derived
428                            , ::_Repo **                   // Base
429                            , Repository                   // Value
430                            , boost::forward_traversal_tag // CategoryOrTraversal
431                            , Repository                   // Reference
432                              >
433       {
434         public:
435           RepositoryIterator()
436           : RepositoryIterator::iterator_adaptor_( 0 )
437           {}
438
439           explicit RepositoryIterator( ::_Repo ** p )
440           : RepositoryIterator::iterator_adaptor_( p )
441           {}
442
443         private:
444           friend class boost::iterator_core_access;
445
446           Repository dereference() const
447           { return Repository( *base() ); }
448
449           void increment();
450       };
451       ///////////////////////////////////////////////////////////////////
452       ///////////////////////////////////////////////////////////////////
453       //
454       //        CLASS NAME : ByRepository
455       //
456       /** Functor filtering \ref Solvable by \ref Repository.*/
457       struct ByRepository
458       {
459         public:
460           ByRepository( const Repository & repository_r ) : _repository( repository_r ) {}
461           ByRepository( sat::detail::RepoIdType id_r ) : _repository( id_r ) {}
462           ByRepository() {}
463
464           bool operator()( const sat::Solvable & slv_r ) const
465           { return slv_r.repository() == _repository; }
466
467         private:
468           Repository _repository;
469       };
470       ///////////////////////////////////////////////////////////////////
471       /////////////////////////////////////////////////////////////////
472     } // namespace detail
473     ///////////////////////////////////////////////////////////////////
474   /////////////////////////////////////////////////////////////////
475 } // namespace zypp
476 ///////////////////////////////////////////////////////////////////
477
478 // Late include as sat::ArrayAttr requires Repository.h
479 #include "zypp/sat/LookupAttrTools.h"
480
481 #endif // ZYPP_SAT_REPOSITORY_H