Imported Upstream version 16.3.2
[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/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"
24
25 ///////////////////////////////////////////////////////////////////
26 namespace zypp
27 { /////////////////////////////////////////////////////////////////
28
29     namespace detail
30     {
31       struct ByRepository;
32     }
33
34     ///////////////////////////////////////////////////////////////////
35     //
36     //  CLASS NAME : Repository
37     //
38     /** */
39     class Repository : protected sat::detail::PoolMember
40     {
41     public:
42         typedef filter_iterator<detail::ByRepository, sat::detail::SolvableIterator> SolvableIterator;
43         typedef sat::detail::size_type size_type;
44         typedef sat::detail::RepoIdType IdType;
45
46         typedef sat::ArrayAttr<std::string,std::string> Keywords;
47
48         typedef std::string ContentRevision;
49         typedef std::string ContentIdentifier;
50
51     public:
52         /** Default ctor creates \ref noRepository.*/
53         Repository()
54         : _id( sat::detail::noRepoId ) {}
55
56         /** \ref PoolImpl ctor. */
57         explicit Repository( IdType id_r )
58         : _id( id_r ) {}
59
60     public:
61         /** Represents no \ref Repository. */
62         static const Repository noRepository;
63
64         /** Evaluate \ref Repository in a boolean context (\c != \c noRepository). */
65         explicit operator bool() const
66         { return get() != nullptr; }
67
68         /** Reserved system repository alias \c @System. */
69         static const std::string & systemRepoAlias();
70
71         /** Return whether this is the system repository. */
72         bool isSystemRepo() const;
73
74     public:
75          /**
76           * Short unique string to identify a repo.
77           * ie: openSUSE-10.3
78           *
79           * If you are looking for a label to display
80           * see \ref name().
81           * ie: "openSUSE 10.3 Main repository"
82           *
83           */
84         std::string alias() const;
85
86         /** Label to display for this repo. */
87         std::string name() const;
88
89         /** Alias or name, according to \ref ZConfig::repoLabelIsAlias */
90         std::string label() const;
91
92         /** User string: \ref label (alias or name) */
93         std::string asUserString() const
94         { return label(); }
95
96     public:
97         /** Timestamp or arbitrary user supplied string.
98          * \c /repomd/revision/text() in \c repomd.xml.
99          */
100         ContentRevision contentRevision() const;
101
102         /** Unique string identifying a repositories content.
103          * \c /repomd/tags/repo/text() in \c repomd.xml.
104          * \code
105          * <repomd ....>
106          *  <tags>
107          *   <repo>obsrepository://build.suse.de/SUSE:Factory:Head:Internal/standard</repo>
108          * \endcode
109          * Semantically the value is just a plain string, even
110          * if OBS often uses the location of the project as
111          * unique identifyer.
112          */
113         ContentIdentifier contentIdentifier() const;
114
115         /** Whether \a id_r matches this repos content identifier. */
116         bool hasContentIdentifier( const ContentIdentifier & id_r ) const;
117
118         /**
119          * Timestamp when this repository was generated
120          *
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.
124          *
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 ).
129          *
130          * The timestamp is 0 if the repository does not
131          * specify when it was generated.
132          *
133          */
134         Date generatedTimestamp() const;
135
136         /**
137          * Suggested expiration timestamp.
138          *
139          * Repositories can define an amount of time
140          * they expire, with the generated timestamp as
141          * the base point of time.
142          *
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
146          * metadata.
147          *
148          * The timestamp is 0 if the repository does not specify
149          * an expiration date.
150          *
151          */
152         Date suggestedExpirationTimestamp() const;
153
154         /**
155          * repository keywords (tags)
156          */
157         Keywords keywords() const;
158
159         /** Whether \a val_r is present in keywords. */
160         bool hasKeyword( const std::string & val_r ) const;
161
162         /**
163          * The suggested expiration date of this repository
164          * already passed
165          *
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
169          */
170         bool maybeOutdated() const;
171
172         /** Hint whether the Repo may provide updates for a product.
173          *
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.
177          */
178         bool isUpdateRepo() const;
179
180         /** Hint whether the Repo may provide updates for a product identified by it's \ref CpeId
181          *
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.
185          */
186         bool providesUpdatesFor( const CpeId & cpeid_r ) const;
187
188         /** Whether \ref Repository contains solvables. */
189         bool solvablesEmpty() const;
190
191         /** Number of solvables in \ref Repository. */
192         size_type solvablesSize() const;
193
194         /** Iterator to the first \ref Solvable. */
195         SolvableIterator solvablesBegin() const;
196
197         /** Iterator behind the last \ref Solvable. */
198         SolvableIterator solvablesEnd() const;
199
200         /** Iterate the repositories Solvables. */
201         Iterable<SolvableIterator> solvables() const;
202
203     public:
204
205       /** Query class for Repository related products */
206       class ProductInfoIterator;
207
208       /**
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
214        */
215       ProductInfoIterator compatibleWithProductBegin() const;
216
217       /**
218        * Get an iterator to the end of the repository
219        * compatible distros.
220        * \see Repository::ProductInfoIterator
221        */
222       ProductInfoIterator compatibleWithProductEnd() const;
223
224       /** Iterate the repository compatible distros. */
225       Iterable<ProductInfoIterator> compatibleWithProduct() const;
226
227
228       /**
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
235        */
236       ProductInfoIterator updatesProductBegin() const;
237
238       /**
239        * Get an iterator to the end of distos the repository
240        * provides upadates for.
241        * \see Repository::ProductInfoIterator
242        */
243       ProductInfoIterator updatesProductEnd() const;
244
245       /** Iterate distos the repository provides upadates for. */
246       Iterable<ProductInfoIterator> updatesProduct() const;
247
248     public:
249         /** Return any associated \ref RepoInfo. */
250         RepoInfo info() const;
251
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.
256          */
257         void setInfo( const RepoInfo & info_r );
258
259         /** Remove any \ref RepoInfo set for this repository. */
260         void clearInfo();
261
262     public:
263         /** Remove this \ref Repository from it's \ref Pool. */
264         void eraseFromPool();
265
266         /** Functor calling \ref eraseFromPool. */
267         struct EraseFromPool;
268
269    public:
270         /** Return next Repository in \ref Pool (or \ref noRepository). */
271         Repository nextInPool() const;
272
273    public:
274         /** \name Repository content manipulating methods.
275          * \todo maybe a separate Repository/Solvable content manip interface
276          * provided by the pool.
277          */
278         //@{
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
284          */
285         void addSolv( const Pathname & file_r );
286
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
293          */
294         void addHelix( const Pathname & file_r );
295
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 ); }
301         //@}
302
303     public:
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).
314          */
315         //@{
316         int satInternalPriority() const;
317         int satInternalSubPriority() const;
318         //@}
319
320     private:
321         IdType _id;
322     };
323     ///////////////////////////////////////////////////////////////////
324
325     /** \relates Repository Stream output */
326     std::ostream & operator<<( std::ostream & str, const Repository & obj );
327
328     /** \relates Repository XML output */
329     std::ostream & dumpAsXmlOn( std::ostream & str, const Repository & obj );
330
331     /** \relates Repository */
332     inline bool operator==( const Repository & lhs, const Repository & rhs )
333     { return lhs.get() == rhs.get(); }
334
335     /** \relates Repository */
336     inline bool operator!=( const Repository & lhs, const Repository & rhs )
337     { return lhs.get() != rhs.get(); }
338
339     /** \relates Repository */
340     inline bool operator<( const Repository & lhs, const Repository & rhs )
341     { return lhs.get() < rhs.get(); }
342
343     ///////////////////////////////////////////////////////////////////
344     /**
345      * Query class for Repository related products
346      *
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
349      *
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.
354      *
355      * \code
356      * for_( it, repo.compatibleWithProductBegin(), repo.compatibleWithProductEnd() )
357      * {
358      *   cout << it.label() << ": " << it.cpeid() << endl;
359      * }
360      * \endcode
361      *
362      */
363     class Repository::ProductInfoIterator : public boost::iterator_adaptor<
364         Repository::ProductInfoIterator    // Derived
365         , sat::LookupAttr::iterator        // Base
366         , int                              // Value
367         , boost::forward_traversal_tag     // CategoryOrTraversal
368         , int                              // Reference
369     >
370     {
371       public:
372         ProductInfoIterator()
373         {}
374
375         /** Product label */
376         std::string label() const;
377
378         /** The Common Platform Enumeration name for this product. */
379         CpeId cpeId() const;
380
381       private:
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 );
385
386       private:
387         friend class boost::iterator_core_access;
388         int dereference() const { return 0; }
389     };
390     ///////////////////////////////////////////////////////////////////
391
392     /** Iterate the repository compatible distros. */
393     inline Iterable<Repository::ProductInfoIterator> Repository::compatibleWithProduct() const
394     { return makeIterable( compatibleWithProductBegin(), compatibleWithProductEnd() ); }
395
396     /** Iterate distos the repository provides upadates for. */
397     inline Iterable<Repository::ProductInfoIterator> Repository::updatesProduct() const
398     { return makeIterable( updatesProductBegin(), updatesProductEnd() ); }
399
400     ///////////////////////////////////////////////////////////////////
401     //
402     //  CLASS NAME : Repository::EraseFromPool
403     //
404     /** Functor removing \ref Repository from it's \ref Pool.
405      *
406      * E.g. used as dispose function in. \ref AutoDispose
407      * to provide a convenient and exception safe temporary
408      * \ref Repository.
409      * \code
410      *  sat::Pool satpool;
411      *  MIL << "1 " << satpool << endl;
412      *  {
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.
419      *  }
420      *  MIL << "3 " << satpool << endl;
421      * \endcode
422      * \code
423      * 1 sat::pool(){0repos|2slov}
424      * 2 sat::pool(){1repos|2612slov}
425      * 3 sat::pool(){0repos|2slov}
426      * \endcode
427      * Leaving the block without calling <tt>tmprepo.resetDispose();</tt>
428      * before, will automatically remove the \ref Repo from it's \ref Pool.
429      */
430     struct Repository::EraseFromPool
431     {
432         void operator()( Repository repository_r ) const
433             { repository_r.eraseFromPool(); }
434     };
435     ///////////////////////////////////////////////////////////////////
436
437     ///////////////////////////////////////////////////////////////////
438     namespace detail
439     { /////////////////////////////////////////////////////////////////
440       ///////////////////////////////////////////////////////////////////
441       //
442       //        CLASS NAME : RepositoryIterator
443       //
444       /** */
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
451                              >
452       {
453         public:
454           RepositoryIterator()
455           : RepositoryIterator::iterator_adaptor_( 0 )
456           {}
457
458           explicit RepositoryIterator( sat::detail::CRepo ** p )
459           : RepositoryIterator::iterator_adaptor_( p )
460           {}
461
462         private:
463           friend class boost::iterator_core_access;
464
465           Repository dereference() const
466           { return Repository( *base() ); }
467
468           void increment();
469       };
470       ///////////////////////////////////////////////////////////////////
471       ///////////////////////////////////////////////////////////////////
472       //
473       //        CLASS NAME : ByRepository
474       //
475       /** Functor filtering \ref Solvable by \ref Repository.*/
476       struct ByRepository
477       {
478         public:
479           ByRepository( const Repository & repository_r ) : _repository( repository_r ) {}
480           ByRepository( sat::detail::RepoIdType id_r ) : _repository( id_r ) {}
481           ByRepository() {}
482
483           bool operator()( const sat::Solvable & slv_r ) const
484           { return slv_r.repository() == _repository; }
485
486         private:
487           Repository _repository;
488       };
489       ///////////////////////////////////////////////////////////////////
490       /////////////////////////////////////////////////////////////////
491     } // namespace detail
492     ///////////////////////////////////////////////////////////////////
493
494     inline Iterable<Repository::SolvableIterator> Repository::solvables() const
495     { return makeIterable( solvablesBegin(), solvablesEnd() ); }
496
497   /////////////////////////////////////////////////////////////////
498 } // namespace zypp
499 ///////////////////////////////////////////////////////////////////
500
501 // Late include as sat::ArrayAttr requires Repository.h
502 #include "zypp/sat/LookupAttrTools.h"
503
504 #endif // ZYPP_SAT_REPOSITORY_H