Imported Upstream version 17.25.4
[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         /** 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
302          */
303         void addTesttags(const Pathname &file_r);
304
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 ); }
310         //@}
311
312     public:
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).
323          */
324         //@{
325         int satInternalPriority() const;
326         int satInternalSubPriority() const;
327         //@}
328     private:
329         IdType _id;
330     };
331     ///////////////////////////////////////////////////////////////////
332
333     /** \relates Repository Stream output */
334     std::ostream & operator<<( std::ostream & str, const Repository & obj );
335
336     /** \relates Repository XML output */
337     std::ostream & dumpAsXmlOn( std::ostream & str, const Repository & obj );
338
339     /** \relates Repository */
340     inline bool operator==( const Repository & lhs, const Repository & rhs )
341     { return lhs.get() == rhs.get(); }
342
343     /** \relates Repository */
344     inline bool operator!=( const Repository & lhs, const Repository & rhs )
345     { return lhs.get() != rhs.get(); }
346
347     /** \relates Repository */
348     inline bool operator<( const Repository & lhs, const Repository & rhs )
349     { return lhs.get() < rhs.get(); }
350
351     ///////////////////////////////////////////////////////////////////
352     /**
353      * Query class for Repository related products
354      *
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
357      *
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.
362      *
363      * \code
364      * for_( it, repo.compatibleWithProductBegin(), repo.compatibleWithProductEnd() )
365      * {
366      *   cout << it.label() << ": " << it.cpeid() << endl;
367      * }
368      * \endcode
369      *
370      */
371     class Repository::ProductInfoIterator : public boost::iterator_adaptor<
372         Repository::ProductInfoIterator    // Derived
373         , sat::LookupAttr::iterator        // Base
374         , int                              // Value
375         , boost::forward_traversal_tag     // CategoryOrTraversal
376         , int                              // Reference
377     >
378     {
379       public:
380         ProductInfoIterator()
381         {}
382
383         /** Product label */
384         std::string label() const;
385
386         /** The Common Platform Enumeration name for this product. */
387         CpeId cpeId() const;
388
389       private:
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 );
393
394       private:
395         friend class boost::iterator_core_access;
396         int dereference() const { return 0; }
397     };
398     ///////////////////////////////////////////////////////////////////
399
400     /** Iterate the repository compatible distros. */
401     inline Iterable<Repository::ProductInfoIterator> Repository::compatibleWithProduct() const
402     { return makeIterable( compatibleWithProductBegin(), compatibleWithProductEnd() ); }
403
404     /** Iterate distos the repository provides upadates for. */
405     inline Iterable<Repository::ProductInfoIterator> Repository::updatesProduct() const
406     { return makeIterable( updatesProductBegin(), updatesProductEnd() ); }
407
408     ///////////////////////////////////////////////////////////////////
409     //
410     //  CLASS NAME : Repository::EraseFromPool
411     //
412     /** Functor removing \ref Repository from it's \ref Pool.
413      *
414      * E.g. used as dispose function in. \ref AutoDispose
415      * to provide a convenient and exception safe temporary
416      * \ref Repository.
417      * \code
418      *  sat::Pool satpool;
419      *  MIL << "1 " << satpool << endl;
420      *  {
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.
427      *  }
428      *  MIL << "3 " << satpool << endl;
429      * \endcode
430      * \code
431      * 1 sat::pool(){0repos|2solv}
432      * 2 sat::pool(){1repos|2612solv}
433      * 3 sat::pool(){0repos|2solv}
434      * \endcode
435      * Leaving the block without calling <tt>tmprepo.resetDispose();</tt>
436      * before, will automatically remove the \ref Repo from it's \ref Pool.
437      */
438     struct Repository::EraseFromPool
439     {
440         void operator()( Repository repository_r ) const
441             { repository_r.eraseFromPool(); }
442     };
443     ///////////////////////////////////////////////////////////////////
444
445     ///////////////////////////////////////////////////////////////////
446     namespace detail
447     { /////////////////////////////////////////////////////////////////
448       ///////////////////////////////////////////////////////////////////
449       //
450       //        CLASS NAME : RepositoryIterator
451       //
452       /** */
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
459                              >
460       {
461         public:
462           RepositoryIterator()
463           : RepositoryIterator::iterator_adaptor_( 0 )
464           {}
465
466           explicit RepositoryIterator( sat::detail::CRepo ** p )
467           : RepositoryIterator::iterator_adaptor_( p )
468           {}
469
470         private:
471           friend class boost::iterator_core_access;
472
473           Repository dereference() const
474           { return Repository( *base() ); }
475
476           void increment();
477       };
478       ///////////////////////////////////////////////////////////////////
479       ///////////////////////////////////////////////////////////////////
480       //
481       //        CLASS NAME : ByRepository
482       //
483       /** Functor filtering \ref Solvable by \ref Repository.*/
484       struct ByRepository
485       {
486         public:
487           ByRepository( const Repository & repository_r ) : _repository( repository_r ) {}
488           ByRepository( sat::detail::RepoIdType id_r ) : _repository( id_r ) {}
489           ByRepository() {}
490
491           bool operator()( const sat::Solvable & slv_r ) const
492           { return slv_r.repository() == _repository; }
493
494         private:
495           Repository _repository;
496       };
497       ///////////////////////////////////////////////////////////////////
498       /////////////////////////////////////////////////////////////////
499     } // namespace detail
500     ///////////////////////////////////////////////////////////////////
501
502     inline Iterable<Repository::SolvableIterator> Repository::solvables() const
503     { return makeIterable( solvablesBegin(), solvablesEnd() ); }
504
505   /////////////////////////////////////////////////////////////////
506 } // namespace zypp
507 ///////////////////////////////////////////////////////////////////
508
509 // Late include as sat::ArrayAttr requires Repository.h
510 #include <zypp/sat/LookupAttrTools.h>
511
512 #endif // ZYPP_SAT_REPOSITORY_H