1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/ResPool.h
12 #ifndef ZYPP_RESPOOL_H
13 #define ZYPP_RESPOOL_H
17 #include "zypp/APIConfig.h"
18 #include "zypp/base/Iterator.h"
20 #include "zypp/pool/PoolTraits.h"
21 #include "zypp/PoolItem.h"
22 #include "zypp/Filter.h"
24 ///////////////////////////////////////////////////////////////////
26 { /////////////////////////////////////////////////////////////////
32 ///////////////////////////////////////////////////////////////////
34 // CLASS NAME : ResPool
36 /** Global ResObject pool.
38 * Explicitly shared singleton.
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.
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:
50 * for_( it, pool.filterBegin(myfilter), pool.filterEnd(myfilter) )
54 * for ( const PoolItem & pi : pool.filter(myfilter) )
58 * \include n_ResPool_nomorenameiter
62 friend std::ostream & operator<<( std::ostream & str, const ResPool & obj );
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;
72 /** Singleton ctor. */
73 static ResPool instance();
76 ResPoolProxy proxy() const;
79 Resolver & resolver() const;
82 /** The pools serial number. Changing whenever the
83 * whenever the content changes. (Resolvables or
86 const SerialNumber & serial() const;
92 size_type size() const;
94 /** \name Iterate over all PoolItems (all kinds). */
97 const_iterator begin() const
98 { return make_filter_begin( pool::ByPoolItem(), store() ); }
100 const_iterator end() const
101 { return make_filter_end( pool::ByPoolItem(), store() ); }
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.
110 PoolItem find( const sat::Solvable & slv_r ) const;
112 PoolItem find( const ResObject::constPtr & resolvable_r ) const
113 { return( resolvable_r ? find( resolvable_r->satSolvable() ) : PoolItem() ); }
116 /** \name Iterate over all PoolItems matching a \c TFilter. */
118 template<class TFilter>
119 filter_iterator<TFilter,const_iterator> filterBegin( const TFilter & filter_r ) const
120 { return make_filter_begin( filter_r, *this ); }
122 template<class TFilter>
123 filter_iterator<TFilter,const_iterator> filterEnd( const TFilter & filter_r ) const
124 { return make_filter_end( filter_r, *this ); }
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 ) ); }
131 /** \name Iterate over all PoolItems by status.
133 * Simply pass the \ref ResStatus predicate you want to use as filter:
135 * // iterate over all orphaned items:
136 * for_( it, pool.byStatusBegin(&ResStatus::isOrphaned), pool.byStatusEnd(&ResStatus::isOrphaned) )
140 * Or use \ref filter::ByStatus in more complex queries:
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) )
150 filter_iterator<filter::ByStatus,const_iterator> byStatusBegin( const filter::ByStatus & filter_r ) const
151 { return make_filter_begin( filter_r, *this ); }
153 filter_iterator<filter::ByStatus,const_iterator> byStatusEnd( const filter::ByStatus & filter_r ) const
154 { return make_filter_end( filter_r, *this ); }
156 Iterable<filter_iterator<filter::ByStatus,const_iterator> > byStatus( const filter::ByStatus & filter_r ) const
157 { return makeIterable( byStatusBegin( filter_r ), byStatusEnd( filter_r ) ); }
161 /** \name Iterate over all PoolItems of a certain name and kind. */
163 typedef pool::ByIdent ByIdent;
164 typedef pool::PoolTraits::byIdent_iterator byIdent_iterator;
166 byIdent_iterator byIdentBegin( const ByIdent & ident_r ) const
168 return make_transform_iterator( id2item().equal_range( ident_r.get() ).first,
169 pool::PoolTraits::Id2ItemValueSelector() );
172 byIdent_iterator byIdentBegin( ResKind kind_r, IdString name_r ) const
173 { return byIdentBegin( ByIdent(kind_r,name_r) ); }
175 byIdent_iterator byIdentBegin( ResKind kind_r, const C_Str & name_r ) const
176 { return byIdentBegin( ByIdent(kind_r,name_r) ); }
179 byIdent_iterator byIdentBegin( IdString name_r ) const
180 { return byIdentBegin( ByIdent(ResTraits<TRes>::kind,name_r) ); }
183 byIdent_iterator byIdentBegin( const C_Str & name_r ) const
184 { return byIdentBegin( ByIdent(ResTraits<TRes>::kind,name_r) ); }
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) ); }
197 byIdent_iterator byIdentEnd( const ByIdent & ident_r ) const
199 return make_transform_iterator( id2item().equal_range( ident_r.get() ).second,
200 pool::PoolTraits::Id2ItemValueSelector() );
203 byIdent_iterator byIdentEnd( ResKind kind_r, IdString name_r ) const
204 { return byIdentEnd( ByIdent(kind_r,name_r) ); }
206 byIdent_iterator byIdentEnd( ResKind kind_r, const C_Str & name_r ) const
207 { return byIdentEnd( ByIdent(kind_r,name_r) ); }
210 byIdent_iterator byIdentEnd( IdString name_r ) const
211 { return byIdentEnd( ByIdent(ResTraits<TRes>::kind,name_r) ); }
214 byIdent_iterator byIdentEnd( const C_Str & name_r ) const
215 { return byIdentEnd( ByIdent(ResTraits<TRes>::kind,name_r) ); }
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) ); }
228 Iterable<byIdent_iterator> byIdent( const ByIdent & ident_r ) const
229 { return makeIterable( byIdentBegin( ident_r ), byIdentEnd( ident_r ) ); }
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 ) ); }
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 ) ); }
238 Iterable<byIdent_iterator> byIdent( IdString name_r ) const
239 { return makeIterable( byIdentBegin<TRes>( name_r ), byIdentEnd<TRes>( name_r ) ); }
242 Iterable<byIdent_iterator> byIdent( const C_Str & name_r ) const
243 { return makeIterable( byIdentBegin<TRes>( name_r ), byIdentEnd<TRes>( name_r ) ); }
245 Iterable<byIdent_iterator> byIdent( const PoolItem & pi_r ) const
246 { return makeIterable( byIdentBegin( pi_r ), byIdentEnd( pi_r ) ); }
248 Iterable<byIdent_iterator> byIdent(sat::Solvable slv_r ) const
249 { return makeIterable( byIdentBegin( slv_r ), byIdentEnd( slv_r ) ); }
251 Iterable<byIdent_iterator> byIdent( IdString ident_r ) const
252 { return makeIterable( byIdentBegin( ident_r ), byIdentEnd( ident_r ) ); }
256 /** \name Iterate over all ResObjects of a certain kind. */
258 typedef filter::ByKind ByKind;
259 typedef filter_iterator<ByKind,const_iterator> byKind_iterator;
261 byKind_iterator byKindBegin( const ResKind & kind_r ) const
262 { return make_filter_begin( ByKind(kind_r), *this ); }
265 byKind_iterator byKindBegin() const
266 { return make_filter_begin( resfilter::byKind<TRes>(), *this ); }
268 byKind_iterator byKindEnd( const ResKind & kind_r ) const
269 { return make_filter_end( ByKind(kind_r), *this ); }
272 byKind_iterator byKindEnd() const
273 { return make_filter_end( resfilter::byKind<TRes>(), *this ); }
275 Iterable<byKind_iterator> byKind( const ResKind & kind_r ) const
276 { return makeIterable( byKindBegin( kind_r ), byKindEnd( kind_r ) ); }
279 Iterable<byKind_iterator> byKind() const
280 { return makeIterable( byKindBegin<TRes>(), byKindEnd<TRes>() ); }
284 /** \name Iterate over all ResObjects with a certain name (all kinds). */
286 typedef zypp::resfilter::ByName ByName;
287 typedef filter_iterator<ByName,const_iterator> byName_iterator;
289 byName_iterator byNameBegin( const std::string & name_r ) const
290 { return make_filter_begin( ByName(name_r), *this ); }
292 byName_iterator byNameEnd( const std::string & name_r ) const
293 { return make_filter_end( ByName(name_r), *this ); }
295 Iterable<byName_iterator> byName( const std::string & name_r ) const
296 { return makeIterable( byNameBegin( name_r ), byNameEnd( name_r ) ); }
300 /** \name Misc Data. */
302 ///////////////////////////////////////////////////////////////////
303 /// A copy of the Pools initial ValidateValues of pseudo installed items.
305 /// AKA Patch status. Whenever the Pools content changes, the status
306 /// of pseudo installed items (like Patches) is computed (roughly whether
307 /// their dependencies are broken or satisfied) and remembered.
309 /// Comparing the items established state against it's current state
310 /// tells how the current transaction would influence the item (break
311 /// or repair a Patch).
313 class EstablishedStates
316 ~EstablishedStates();
317 /** Map holding pseudo installed items where current and established status differ. */
318 typedef std::map<PoolItem,ResStatus::ValidateValue> ChangedPseudoInstalled;
319 /** Return all pseudo installed items whose current state differs from the established one */
320 ChangedPseudoInstalled changedPseudoInstalled() const;
323 RW_pointer<Impl> _pimpl;
325 friend class pool::PoolImpl;
326 /** Factory: \ref ResPool::establishedStates */
327 EstablishedStates( shared_ptr<Impl> pimpl_r )
331 ///////////////////////////////////////////////////////////////////
333 /** Factory for \ref EstablishedStates.
334 * A few internal algorithms benefit from keeping an instance across pool
335 * content changes. User code usually want's to call \ref changedPseudoInstalled
338 EstablishedStates establishedStates() const;
340 /** Map holding pseudo installed items where current and established status differ. */
341 typedef EstablishedStates::ChangedPseudoInstalled ChangedPseudoInstalled;
343 /** Return all pseudo installed items whose current state differs from their initial one.
344 * E.g. a Patch may become SATISFIED by updating the packages it refers to.
345 * For this to happen it does not matter whether you selected the Patch or
346 * whether you selected the individual Packages.
347 * A Patches status is computed and updated with every solver run.
349 ChangedPseudoInstalled changedPseudoInstalled() const
350 { return establishedStates().changedPseudoInstalled(); }
353 /** \name Iterate over all Repositories that contribute ResObjects.
356 size_type knownRepositoriesSize() const;
358 repository_iterator knownRepositoriesBegin() const;
360 repository_iterator knownRepositoriesEnd() const;
362 /** Find a \ref Repository named \c alias_r.
363 * Returns \ref Repository::noRepository if there is no such \ref Repository.
365 Repository reposFind( const std::string & alias_r ) const;
367 Iterable<repository_iterator> knownRepositories() const
368 { return makeIterable( knownRepositoriesBegin(), knownRepositoriesEnd() ); }
372 /** \name Handle locale support.
374 * A \ref filter::ByLocaleSupport is provided to iterate over
375 * all items supporting a specific locale.
377 * \see \ref sat::LocaleSupport for a more convenient interface.
380 * ResPool pool( ResPool::instance() );
382 * filter::ByLocaleSupport f( Locale("de") );
383 * for_( it, pool.filterBegin(f), pool.filterEnd(f) )
385 * MIL << *it << endl; // supporting "de"
388 * f = filter::ByLocaleSupport( pool.getRequestedLocales() );
389 * for_( it, pool.filterBegin(f), pool.filterEnd(f) )
391 * MIL << *it << endl; // supporting any requested locale
396 /** Set the requested locales.
397 * Languages to be supported by the system, e.g. language specific
398 * packages to be installed.
400 void setRequestedLocales( const LocaleSet & locales_r );
402 /** Add one \ref Locale to the set of requested locales.
403 * Return \c true if \c locale_r was newly added to the set.
405 bool addRequestedLocale( const Locale & locale_r );
407 /** Erase one \ref Locale from the set of requested locales.
408 * Return \c false if \c locale_r was not found in the set.
410 bool eraseRequestedLocale( const Locale & locale_r );
412 /** Return the requested locales.
413 * \see \ref setRequestedLocales
415 const LocaleSet & getRequestedLocales() const;
417 /** Whether this \ref Locale is in the set of requested locales. */
418 bool isRequestedLocale( const Locale & locale_r ) const;
420 /** Get the set of available locales.
421 * This is computed from the package data so it actually
422 * represents all locales packages claim to support.
424 const LocaleSet & getAvailableLocales() const;
426 /** Whether this \ref Locale is in the set of available locales. */
427 bool isAvailableLocale( const Locale & locale_r ) const;
431 /** \name Handle hard locks (e.g set from /etc/zypp/locks).
433 * As this kind of lock is query based, it's quite expensive.
435 * These queries are re-evaluated when adding new repos to the pool.
438 typedef pool::PoolTraits::HardLockQueries HardLockQueries;
439 typedef pool::PoolTraits::hardLockQueries_iterator hardLockQueries_iterator;
441 bool hardLockQueriesEmpty() const;
442 size_type hardLockQueriesSize() const;
443 hardLockQueries_iterator hardLockQueriesBegin() const;
444 hardLockQueries_iterator hardLockQueriesEnd() const;
446 Iterable<hardLockQueries_iterator> hardLockQueries() const
447 { return makeIterable( hardLockQueriesBegin(), hardLockQueriesEnd() ); }
449 /** Set a new set of queries.
450 * The hard-locks of existing PoolItems are adjusted according
451 * to the queries. (usually called on target load)
453 void setHardLockQueries( const HardLockQueries & newLocks_r );
455 /** Suggest a new set of queries based on the current selection.
456 * (usually remembered on commit).
458 void getHardLockQueries( HardLockQueries & activeLocks_r );
462 const pool::PoolTraits::ItemContainerT & store() const;
463 const pool::PoolTraits::Id2ItemT & id2item() const;
467 ResPool( pool::PoolTraits::Impl_Ptr impl_r );
468 /** Access to implementation. */
469 RW_pointer<pool::PoolTraits::Impl> _pimpl;
471 ///////////////////////////////////////////////////////////////////
473 /** \relates ResPool Stream output */
474 std::ostream & operator<<( std::ostream & str, const ResPool & obj );
476 /////////////////////////////////////////////////////////////////
478 ///////////////////////////////////////////////////////////////////
480 #include "zypp/ResPoolProxy.h"
482 #endif // ZYPP_RESPOOL_H