Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / ResPool.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/ResPool.h
10  *
11 */
12 #ifndef ZYPP_RESPOOL_H
13 #define ZYPP_RESPOOL_H
14
15 #include <iosfwd>
16
17 #include "zypp/APIConfig.h"
18 #include "zypp/base/Iterator.h"
19
20 #include "zypp/pool/PoolTraits.h"
21 #include "zypp/PoolItem.h"
22 #include "zypp/Filter.h"
23
24 ///////////////////////////////////////////////////////////////////
25 namespace zypp
26 { /////////////////////////////////////////////////////////////////
27
28   class SerialNumber;
29   class ResPoolProxy;
30   class Resolver;
31
32   ///////////////////////////////////////////////////////////////////
33   //
34   //    CLASS NAME : ResPool
35   //
36   /** Global ResObject pool.
37    *
38    * Explicitly shared singleton.
39    *
40    * \note Filter iterators provided by ResPool are intended to
41    * operate on internal index tables for faster access. If the
42    * the index is not yet implemented, they are realized as
43    * an ordinary filter iterator. Do not provide filter iterators
44    * here, if there is no index table for it.
45    *
46    * For most (*Begin,*End) iterator-pairs there's also an \ref Iterable
47    * provided, so you can use then in range-based for loops:
48    * \code
49    *   // classic:
50    *   for_( it, pool.filterBegin(myfilter), pool.filterEnd(myfilter) )
51    *   { ... }
52    *
53    *   // range based:
54    *   for ( const PoolItem & pi : pool.filter(myfilter) )
55    *   { ... }
56    * \endcode
57    *
58    * \include n_ResPool_nomorenameiter
59   */
60   class ResPool
61   {
62     friend std::ostream & operator<<( std::ostream & str, const ResPool & obj );
63
64     public:
65       /** \ref PoolItem */
66       typedef PoolItem                                   value_type;
67       typedef pool::PoolTraits::size_type                size_type;
68       typedef pool::PoolTraits::const_iterator           const_iterator;
69       typedef pool::PoolTraits::repository_iterator      repository_iterator;
70
71     public:
72       /** Singleton ctor. */
73       static ResPool instance();
74
75       /** preliminary */
76       ResPoolProxy proxy() const;
77
78       /** The Resolver */
79       Resolver & resolver() const;
80
81     public:
82       /** The pools serial number. Changing whenever the
83        * whenever the content changes. (Resolvables or
84        * Dependencies).
85        */
86       const SerialNumber & serial() const;
87
88     public:
89       /**  */
90       bool empty() const;
91       /**  */
92       size_type size() const;
93
94       /** \name Iterate over all PoolItems (all kinds). */
95       //@{
96       /** */
97       const_iterator begin() const
98       { return make_filter_begin( pool::ByPoolItem(), store() ); }
99       /** */
100       const_iterator end() const
101       { return make_filter_end( pool::ByPoolItem(), store() ); }
102       //@}
103
104     public:
105       /** Return the corresponding \ref PoolItem.
106        * Pool and sat pool should be in sync. Returns an empty
107        * \ref PoolItem if there is no corresponding \ref PoolItem.
108        * \see \ref PoolItem::satSolvable.
109        */
110       PoolItem find( const sat::Solvable & slv_r ) const;
111       /** \overload */
112       PoolItem find( const ResObject::constPtr & resolvable_r ) const
113       { return( resolvable_r ? find( resolvable_r->satSolvable() ) : PoolItem() ); }
114
115     public:
116       /** \name Iterate over all PoolItems matching a \c TFilter. */
117       //@{
118       template<class TFilter>
119       filter_iterator<TFilter,const_iterator> filterBegin( const TFilter & filter_r ) const
120       { return make_filter_begin( filter_r, *this ); }
121
122       template<class TFilter>
123       filter_iterator<TFilter,const_iterator> filterEnd( const TFilter & filter_r ) const
124       { return make_filter_end( filter_r, *this ); }
125
126       template<class TFilter>
127       Iterable<filter_iterator<TFilter,const_iterator> > filter( const TFilter & filter_r ) const
128       { return makeIterable( filterBegin( filter_r ), filterEnd( filter_r ) ); }
129       //@}
130
131       /** \name Iterate over all PoolItems by status.
132        *
133        * Simply pass the \ref ResStatus predicate you want to use as filter:
134        * \code
135        *   // iterate over all orphaned items:
136        *   for_( it, pool.byStatusBegin(&ResStatus::isOrphaned), pool.byStatusEnd(&ResStatus::isOrphaned) )
137        *   {...}
138        * \endcode
139        *
140        * Or use \ref filter::ByStatus in more complex queries:
141        * \code
142        *   // iterate over all (orphaned and recommended) items:
143        *   functor::Chain<filter::ByStatus,filter::ByStatus> myfilter( filter::ByStatus(&ResStatus::isOrphaned),
144        *                                                               filter::ByStatus(&ResStatus::isRecommended) );
145        *   for_( it, pool.filterBegin(myfilter), pool.filterEnd(myfilter) )
146        *   { ... }
147        * \endcode
148        */
149       //@{
150       filter_iterator<filter::ByStatus,const_iterator> byStatusBegin( const filter::ByStatus & filter_r ) const
151       { return make_filter_begin( filter_r, *this ); }
152
153       filter_iterator<filter::ByStatus,const_iterator> byStatusEnd( const filter::ByStatus & filter_r ) const
154       { return make_filter_end( filter_r, *this ); }
155
156       Iterable<filter_iterator<filter::ByStatus,const_iterator> > byStatus( const filter::ByStatus & filter_r ) const
157       { return makeIterable( byStatusBegin( filter_r ), byStatusEnd( filter_r ) ); }
158       //@}
159
160     public:
161       /** \name Iterate over all PoolItems of a certain name and kind. */
162       //@{
163       typedef pool::ByIdent                       ByIdent;
164       typedef pool::PoolTraits::byIdent_iterator  byIdent_iterator;
165
166       byIdent_iterator byIdentBegin( const ByIdent & ident_r ) const
167       {
168         return make_transform_iterator( id2item().equal_range( ident_r.get() ).first,
169                                         pool::PoolTraits::Id2ItemValueSelector() );
170       }
171
172       byIdent_iterator byIdentBegin( ResKind kind_r, IdString name_r ) const
173       { return byIdentBegin( ByIdent(kind_r,name_r) ); }
174
175       byIdent_iterator byIdentBegin( ResKind kind_r, const C_Str & name_r ) const
176       { return byIdentBegin( ByIdent(kind_r,name_r) ); }
177
178       template<class TRes>
179       byIdent_iterator byIdentBegin( IdString name_r ) const
180       { return byIdentBegin( ByIdent(ResTraits<TRes>::kind,name_r) ); }
181
182       template<class TRes>
183       byIdent_iterator byIdentBegin( const C_Str & name_r ) const
184       { return byIdentBegin( ByIdent(ResTraits<TRes>::kind,name_r) ); }
185
186       /** Derive name and kind from \ref PoolItem. */
187       byIdent_iterator byIdentBegin( const PoolItem & pi_r ) const
188       { return byIdentBegin( ByIdent(pi_r.satSolvable()) ); }
189       /** Derive name and kind from \ref sat::Solvable. */
190       byIdent_iterator byIdentBegin( sat::Solvable slv_r ) const
191       { return byIdentBegin( ByIdent(slv_r) ); }
192       /** Takes a \ref sat::Solvable::ident string. */
193       byIdent_iterator byIdentBegin( IdString ident_r ) const
194       { return byIdentBegin( ByIdent(ident_r) ); }
195
196
197       byIdent_iterator byIdentEnd( const ByIdent & ident_r ) const
198       {
199         return make_transform_iterator( id2item().equal_range( ident_r.get() ).second,
200                                         pool::PoolTraits::Id2ItemValueSelector() );
201       }
202
203       byIdent_iterator byIdentEnd( ResKind kind_r, IdString name_r ) const
204       { return byIdentEnd( ByIdent(kind_r,name_r) ); }
205
206       byIdent_iterator byIdentEnd( ResKind kind_r, const C_Str & name_r ) const
207       { return byIdentEnd( ByIdent(kind_r,name_r) ); }
208
209       template<class TRes>
210       byIdent_iterator byIdentEnd( IdString name_r ) const
211       { return byIdentEnd( ByIdent(ResTraits<TRes>::kind,name_r) ); }
212
213       template<class TRes>
214       byIdent_iterator byIdentEnd( const C_Str & name_r ) const
215       { return byIdentEnd( ByIdent(ResTraits<TRes>::kind,name_r) ); }
216
217       /** Derive name and kind from \ref PoolItem. */
218       byIdent_iterator byIdentEnd( const PoolItem & pi_r ) const
219       { return byIdentEnd( ByIdent(pi_r.satSolvable()) ); }
220       /** Derive name and kind from \ref sat::Solvable. */
221       byIdent_iterator byIdentEnd( sat::Solvable slv_r ) const
222       { return byIdentEnd( ByIdent(slv_r) ); }
223       /** Takes a \ref sat::Solvable::ident string. */
224       byIdent_iterator byIdentEnd( IdString ident_r ) const
225       { return byIdentEnd( ByIdent(ident_r) ); }
226
227
228       Iterable<byIdent_iterator> byIdent( const ByIdent & ident_r ) const
229       { return makeIterable( byIdentBegin( ident_r ), byIdentEnd( ident_r ) ); }
230
231       Iterable<byIdent_iterator> byIdent( ResKind kind_r, IdString name_r ) const
232       { return makeIterable( byIdentBegin( kind_r, name_r ), byIdentEnd(  kind_r, name_r ) ); }
233
234       Iterable<byIdent_iterator> byIdent( ResKind kind_r, const C_Str & name_r ) const
235       { return makeIterable( byIdentBegin(  kind_r, name_r ), byIdentEnd(  kind_r, name_r ) ); }
236
237       template<class TRes>
238       Iterable<byIdent_iterator> byIdent( IdString name_r ) const
239       { return makeIterable( byIdentBegin<TRes>( name_r ), byIdentEnd<TRes>( name_r ) ); }
240
241       template<class TRes>
242       Iterable<byIdent_iterator> byIdent( const C_Str & name_r ) const
243       { return makeIterable( byIdentBegin<TRes>( name_r ), byIdentEnd<TRes>( name_r ) ); }
244
245       Iterable<byIdent_iterator> byIdent( const PoolItem & pi_r ) const
246       { return makeIterable( byIdentBegin( pi_r ), byIdentEnd( pi_r ) ); }
247
248       Iterable<byIdent_iterator> byIdent(sat::Solvable slv_r ) const
249       { return makeIterable( byIdentBegin( slv_r ), byIdentEnd( slv_r ) ); }
250
251       Iterable<byIdent_iterator> byIdent( IdString ident_r ) const
252       { return makeIterable( byIdentBegin( ident_r ), byIdentEnd( ident_r ) ); }
253      //@}
254
255     public:
256       /** \name Iterate over all ResObjects of a certain kind. */
257       //@{
258       typedef filter::ByKind ByKind;
259       typedef filter_iterator<ByKind,const_iterator> byKind_iterator;
260
261       byKind_iterator byKindBegin( const ResKind & kind_r ) const
262       { return make_filter_begin( ByKind(kind_r), *this ); }
263
264       template<class TRes>
265           byKind_iterator byKindBegin() const
266       { return make_filter_begin( resfilter::byKind<TRes>(), *this ); }
267
268       byKind_iterator byKindEnd( const ResKind & kind_r ) const
269       { return make_filter_end( ByKind(kind_r), *this ); }
270
271       template<class TRes>
272           byKind_iterator byKindEnd() const
273       { return make_filter_end( resfilter::byKind<TRes>(), *this ); }
274
275       Iterable<byKind_iterator> byKind( const ResKind & kind_r ) const
276       { return makeIterable( byKindBegin( kind_r ), byKindEnd( kind_r ) ); }
277
278       template<class TRes>
279       Iterable<byKind_iterator> byKind() const
280       { return makeIterable( byKindBegin<TRes>(), byKindEnd<TRes>() ); }
281       //@}
282
283     public:
284       /** \name Iterate over all ResObjects with a certain name (all kinds). */
285       //@{
286       typedef zypp::resfilter::ByName ByName;
287       typedef filter_iterator<ByName,const_iterator> byName_iterator;
288
289       byName_iterator byNameBegin( const std::string & name_r ) const
290       { return make_filter_begin( ByName(name_r), *this ); }
291
292       byName_iterator byNameEnd( const std::string & name_r ) const
293       { return make_filter_end( ByName(name_r), *this ); }
294
295       Iterable<byName_iterator> byName( const std::string & name_r ) const
296       { return makeIterable( byNameBegin( name_r ), byNameEnd( name_r ) ); }
297       //@}
298
299     public:
300       /** \name Special iterators. */
301       //@{
302
303       //@}
304    public:
305       /** \name Iterate over all Repositories that contribute ResObjects.
306        */
307       //@{
308       size_type knownRepositoriesSize() const;
309
310       repository_iterator knownRepositoriesBegin() const;
311
312       repository_iterator knownRepositoriesEnd() const;
313
314       /** Find a \ref Repository named \c alias_r.
315        * Returns \ref Repository::noRepository if there is no such \ref Repository.
316        */
317       Repository reposFind( const std::string & alias_r ) const;
318
319       Iterable<repository_iterator> knownRepositories() const
320       { return makeIterable( knownRepositoriesBegin(), knownRepositoriesEnd() ); }
321       //@}
322
323     public:
324       /** \name Handle locale support.
325        *
326        * A \ref filter::ByLocaleSupport is provided to iterate over
327        * all items supporting a specific locale.
328        *
329        * \see \ref sat::LocaleSupport for a more convenient interface.
330        *
331        * \code
332        * ResPool pool( ResPool::instance() );
333        *
334        * filter::ByLocaleSupport f( Locale("de") );
335        * for_( it, pool.filterBegin(f), pool.filterEnd(f) )
336        * {
337        *   MIL << *it << endl; // supporting "de"
338        * }
339        *
340        * f = filter::ByLocaleSupport( pool.getRequestedLocales() );
341        * for_( it, pool.filterBegin(f), pool.filterEnd(f) )
342        * {
343        *   MIL << *it << endl; // supporting any requested locale
344        * }
345        * \endcode
346        */
347       //@{
348       /** Set the requested locales.
349        * Languages to be supported by the system, e.g. language specific
350        * packages to be installed.
351        */
352       void setRequestedLocales( const LocaleSet & locales_r );
353
354       /** Add one \ref Locale to the set of requested locales.
355        * Return \c true if \c locale_r was newly added to the set.
356       */
357       bool addRequestedLocale( const Locale & locale_r );
358
359       /** Erase one \ref Locale from the set of requested locales.
360       * Return \c false if \c locale_r was not found in the set.
361        */
362       bool eraseRequestedLocale( const Locale & locale_r );
363
364       /** Return the requested locales.
365        * \see \ref setRequestedLocales
366       */
367       const LocaleSet & getRequestedLocales() const;
368
369       /** Whether this \ref Locale is in the set of requested locales. */
370       bool isRequestedLocale( const Locale & locale_r ) const;
371
372       /** Get the set of available locales.
373        * This is computed from the package data so it actually
374        * represents all locales packages claim to support.
375        */
376       const LocaleSet & getAvailableLocales() const;
377
378       /** Whether this \ref Locale is in the set of available locales. */
379       bool isAvailableLocale( const Locale & locale_r ) const;
380       //@}
381
382     public:
383       /** \name Handle hard locks (e.g set from /etc/zypp/locks).
384        *
385        * As this kind of lock is query based, it's quite expensive.
386        *
387        * These queries are re-evaluated when adding new repos to the pool.
388        */
389       //@{
390       typedef pool::PoolTraits::HardLockQueries           HardLockQueries;
391       typedef pool::PoolTraits::hardLockQueries_iterator  hardLockQueries_iterator;
392
393       bool hardLockQueriesEmpty() const;
394       size_type hardLockQueriesSize() const;
395       hardLockQueries_iterator hardLockQueriesBegin() const;
396       hardLockQueries_iterator hardLockQueriesEnd() const;
397
398       Iterable<hardLockQueries_iterator> hardLockQueries() const
399       { return makeIterable( hardLockQueriesBegin(), hardLockQueriesEnd() ); }
400
401       /** Set a new set of queries.
402        * The hard-locks of existing PoolItems are adjusted according
403        * to the queries. (usually called on target load)
404        */
405       void setHardLockQueries( const HardLockQueries & newLocks_r );
406
407       /** Suggest a new set of queries based on the current selection.
408        * (usually remembered on commit).
409        */
410       void getHardLockQueries( HardLockQueries & activeLocks_r );
411       //@}
412
413     private:
414       const pool::PoolTraits::ItemContainerT & store() const;
415       const pool::PoolTraits::Id2ItemT & id2item() const;
416
417     private:
418       /** Ctor */
419       ResPool( pool::PoolTraits::Impl_Ptr impl_r );
420       /** Access to implementation. */
421       RW_pointer<pool::PoolTraits::Impl> _pimpl;
422   };
423   ///////////////////////////////////////////////////////////////////
424
425   /** \relates ResPool Stream output */
426   std::ostream & operator<<( std::ostream & str, const ResPool & obj );
427
428   /////////////////////////////////////////////////////////////////
429 } // namespace zypp
430 ///////////////////////////////////////////////////////////////////
431
432 #include "zypp/ResPoolProxy.h"
433
434 #endif // ZYPP_RESPOOL_H