02fe1321695a4ba50f3ea1f87415179808795191
[platform/upstream/libzypp.git] / zypp / sat / Solvable.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/sat/Solvable.h
10  *
11 */
12 #ifndef ZYPP_SAT_SOLVABLE_H
13 #define ZYPP_SAT_SOLVABLE_H
14
15 #include <iosfwd>
16
17 #include "zypp/sat/detail/PoolMember.h"
18 #include "zypp/sat/SolvAttr.h"
19 #include "zypp/ResTraits.h"
20 #include "zypp/IdString.h"
21 #include "zypp/Edition.h"
22 #include "zypp/Arch.h"
23 #include "zypp/Dep.h"
24 #include "zypp/Capabilities.h"
25 #include "zypp/Capability.h"
26 #include "zypp/Locale.h"
27
28 ///////////////////////////////////////////////////////////////////
29 namespace zypp
30 { /////////////////////////////////////////////////////////////////
31
32   class CheckSum;
33   class OnMediaLocation;
34
35   ///////////////////////////////////////////////////////////////////
36   namespace sat
37   { /////////////////////////////////////////////////////////////////
38
39     ///////////////////////////////////////////////////////////////////
40     //
41     //  CLASS NAME : Solvable
42     //
43     /** A \ref Solvable object within the sat \ref Pool.
44      *
45      * \note Unfortunately libsolv combines the objects kind and
46      * name in a single identifier \c "pattern:kde_multimedia",
47      * \b except for packages and source packes. They are not prefixed
48      * by any kind string. Instead the architecture is abused to store
49      * \c "src" and \c "nosrc" values.
50      *
51      * \ref Solvable will hide this inconsistency by treating source
52      * packages as an own kind of solvable and map their arch to
53      * \ref Arch_noarch.
54      */
55     class Solvable : protected detail::PoolMember
56     {
57       public:
58         typedef sat::detail::SolvableIdType IdType;
59
60       public:
61         /** Default ctor creates \ref noSolvable.*/
62         Solvable()
63         : _id( detail::noSolvableId ) {}
64
65         /** \ref PoolImpl ctor. */
66         explicit Solvable( IdType id_r )
67         : _id( id_r ) {}
68
69       public:
70         /** Represents no \ref Solvable. */
71         static const Solvable noSolvable;
72
73         /** Evaluate \ref Solvable in a boolean context (\c != \c noSolvable). */
74         explicit operator bool() const
75         { return get(); }
76
77         /** Return whether this \ref Solvable belongs to the system repo.
78          * \note This includes the otherwise hidden systemSolvable.
79          */
80         bool isSystem() const;
81
82         /** Whether this is known to be installed on behalf of a user request.
83          * \note This is a hint guessed by evaluating an available install history.
84          * Returns \c false for non-system (uninstalled) solvables, or if no history
85          * is available.
86          */
87         bool onSystemByUser() const;
88
89         /** The \ref Repository this \ref Solvable belongs to. */
90         Repository repository() const;
91
92       public:
93
94         /** \name Attribute lookup.
95          * \see \ref LookupAttr and  \ref ArrayAttr providing a general, more
96          * query like interface for attribute retrieval.
97         */
98         //@{
99         /**
100          * returns the string attribute value for \ref attr
101          * or an empty string if it does not exists.
102          */
103         std::string lookupStrAttribute( const SolvAttr & attr ) const;
104         /** \overload Trying to look up a translated string attribute.
105          *
106          * Returns the translation for \c lang_r.
107          *
108          * Passing an empty \ref Locale will return the string for the
109          * current default locale (\see \ref ZConfig::TextLocale),
110          * \b considering all fallback locales.
111          *
112          * Returns an empty string if no translation is available.
113         */
114         std::string lookupStrAttribute( const SolvAttr & attr, const Locale & lang_r ) const;
115
116         /**
117          * returns the numeric attribute value for \ref attr
118          * or 0 if it does not exists.
119          */
120         unsigned long long lookupNumAttribute( const SolvAttr & attr ) const;
121
122         /**
123          * returns the boolean attribute value for \ref attr
124          * or \c false if it does not exists.
125          */
126         bool lookupBoolAttribute( const SolvAttr & attr ) const;
127
128        /**
129          * returns the id attribute value for \ref attr
130          * or \ref detail::noId if it does not exists.
131          */
132         detail::IdType lookupIdAttribute( const SolvAttr & attr ) const;
133
134        /**
135          * returns the CheckSum attribute value for \ref attr
136          * or an empty CheckSum if ir does not exist.
137          */
138         CheckSum lookupCheckSumAttribute( const SolvAttr & attr ) const;
139
140         /**
141          * returns OnMediaLocation data: This is everything we need to
142          * download e.g. an rpm (path, checksum, downloadsize, etc.).
143          */
144         OnMediaLocation lookupLocation() const;
145
146         //@}
147       public:
148         /** The identifier.
149          * This is the solvables \ref name, \b except for packages and
150          * source packes, prefixed by it's \ref kind.
151          */
152         IdString     ident()    const;
153
154         ResKind      kind()     const;
155         /** Test whether a Solvable is of a certain \ref ResKind.
156          * The test is far cheaper than actually retriveing and
157          * comparing the \ref kind.
158          */
159         bool isKind( const ResKind & kind_r ) const;
160         /** \overload */
161         template<class _Res>
162         bool isKind() const
163         { return isKind( resKind<_Res>() ); }
164         /** \overload Extend the test to a range of \ref ResKind. */
165         template<class _Iterator>
166         bool isKind( _Iterator begin, _Iterator end )
167         { for_( it, begin, end ) if ( isKind( *it ) ) return true; return false; }
168
169         std::string  name()     const;
170         Edition      edition()  const;
171         Arch         arch()     const;
172
173         IdString     vendor()   const;
174
175         /** Whether different versions of this package can be installed at the same time.
176          * Per default \c false. \see also \ref ZConfig::multiversion.
177          */
178         bool         multiversionInstall() const;
179
180         /** String representation <tt>"ident-edition.arch"</tt> or \c "noSolvable"
181          * \code
182          *   product:openSUSE-11.1.x86_64
183          *   autoyast2-2.16.19-0.1.src
184          *   noSolvable
185          * \endcode
186         */
187         std::string asString() const;
188
189         /** String representation <tt>"ident-edition.arch(repo)"</tt> or \c "noSolvable" */
190         std::string asUserString() const;
191
192         /** Test whether two Solvables have the same content.
193          * Basically the same name, edition, arch, vendor and buildtime.
194          */
195         bool identical( Solvable rhs ) const;
196
197         /** Test for same name-version-release.arch */
198         bool sameNVRA( Solvable rhs ) const
199         { return( ident() == rhs.ident() && edition() == rhs.edition() && arch() == rhs.arch() ); }
200
201      public:
202
203         /** \name Access to the \ref Solvable dependencies.
204          *
205          * \note Prerequires are a subset of requires.
206          */
207         //@{
208         Capabilities operator[]( Dep which_r ) const;
209
210         Capabilities provides()    const;
211         Capabilities requires()    const;
212         Capabilities conflicts()   const;
213         Capabilities obsoletes()   const;
214         Capabilities recommends()  const;
215         Capabilities suggests()    const;
216         Capabilities enhances()    const;
217         Capabilities supplements() const;
218         Capabilities prerequires() const;
219
220         /** Return the namespaced provides <tt>'namespace([value])[ op edition]'</tt> of this Solvable. */
221         CapabilitySet providesNamespace( const std::string & namespace_r ) const;
222
223         /** Return <tt>'value[ op edition]'</tt> for namespaced provides <tt>'namespace(value)[ op edition]'</tt>.
224          * Similar to \ref providesNamespace, but the namespace is stripped from the
225          * dependencies. This is convenient if the namespace denotes packages that
226          * should be looked up. E.g. the \c weakremover namespace used in a products
227          * release package denotes the packages that were dropped from the distribution.
228          * \see \ref Product::droplist
229          */
230         CapabilitySet valuesOfNamespace( const std::string & namespace_r ) const;
231         //@}
232
233       public:
234         /** \name Locale support. */
235         //@{
236         /** Whether this \c Solvable claims to support locales. */
237         bool supportsLocales() const;
238         /** Whether this \c Solvable supports a specific \ref Locale. */
239         bool supportsLocale( const Locale & locale_r ) const;
240         /** Whether this \c Solvable supports at least one of the specified locales. */
241         bool supportsLocale( const LocaleSet & locales_r ) const;
242         /** Whether this \c Solvable supports at least one requested locale.
243          * \see \ref Pool::setRequestedLocales
244         */
245         bool supportsRequestedLocales() const;
246         /** Return the supported locales via locales_r. */
247         void getSupportedLocales( LocaleSet & locales_r ) const;
248         /** \overload */
249         LocaleSet getSupportedLocales() const
250         { LocaleSet ret; getSupportedLocales( ret ); return ret; }
251         //@}
252
253       public:
254         /** Return next Solvable in \ref Pool (or \ref noSolvable). */
255         Solvable nextInPool() const;
256         /** Return next Solvable in \ref Repo (or \ref noSolvable). */
257         Solvable nextInRepo() const;
258
259         /** Helper that splits an identifier into kind and name or vice versa.
260          * \note In case \c name_r is preceded by a well known kind spec, the
261          * \c kind_r argument is ignored, and kind is derived from name.
262          * \see \ref ident
263          */
264         class SplitIdent
265         {
266           public:
267             SplitIdent() {}
268             SplitIdent( IdString ident_r );
269             SplitIdent( const char * ident_r );
270             SplitIdent( const std::string & ident_r );
271             SplitIdent( ResKind kind_r, IdString name_r );
272             SplitIdent( ResKind kind_r, const C_Str & name_r );
273
274             IdString ident() const { return _ident; }
275             ResKind  kind()  const { return _kind; }
276             IdString name()  const { return _name; }
277
278           private:
279             IdString  _ident;
280             ResKind   _kind;
281             IdString  _name;
282         };
283
284       public:
285         /** Expert backdoor. */
286         detail::CSolvable * get() const;
287         /** Expert backdoor. */
288         IdType id() const { return _id; }
289
290       private:
291         IdType _id;
292     };
293     ///////////////////////////////////////////////////////////////////
294
295     /** \relates Solvable Stream output */
296     std::ostream & operator<<( std::ostream & str, const Solvable & obj );
297
298     /** \relates Solvable More verbose stream output including dependencies */
299     std::ostream & dumpOn( std::ostream & str, const Solvable & obj );
300
301     /** \relates Solvable XML output */
302     std::ostream & dumpAsXmlOn( std::ostream & str, const Solvable & obj );
303
304     /** \relates Solvable */
305     inline bool operator==( const Solvable & lhs, const Solvable & rhs )
306     { return lhs.get() == rhs.get(); }
307
308     /** \relates Solvable */
309     inline bool operator!=( const Solvable & lhs, const Solvable & rhs )
310     { return lhs.get() != rhs.get(); }
311
312     /** \relates Solvable */
313     inline bool operator<( const Solvable & lhs, const Solvable & rhs )
314     { return lhs.get() < rhs.get(); }
315
316     /** \relates Solvable Test for same content. */
317     inline bool identical( Solvable lhs, Solvable rhs )
318     { return lhs.identical( rhs ); }
319
320     /** \relates Solvable Test for same name version release and arch. */
321     inline bool sameNVRA( Solvable lhs, Solvable rhs )
322     { return lhs.sameNVRA( rhs ); }
323
324
325     /** \relates Solvable Compare according to \a kind and \a name. */
326     inline int compareByN( const Solvable & lhs, const Solvable & rhs )
327     {
328       int res = 0;
329       if ( lhs != rhs )
330       {
331        if ( (res = lhs.kind().compare( rhs.kind() )) == 0 )
332          res = lhs.name().compare( rhs.name() );
333       }
334       return res;
335     }
336
337     /** \relates Solvable Compare according to \a kind, \a name and \a edition. */
338     inline int compareByNVR( const Solvable & lhs, const Solvable & rhs )
339     {
340       int res = compareByN( lhs, rhs );
341       if ( res == 0 )
342        res = lhs.edition().compare( rhs.edition() );
343       return res;
344     }
345
346     /** \relates Solvable Compare according to \a kind, \a name, \a edition and \a arch. */
347     inline int compareByNVRA( const Solvable & lhs, const Solvable & rhs )
348     {
349       int res = compareByNVR( lhs, rhs );
350       if ( res == 0 )
351        res = lhs.arch().compare( rhs.arch() );
352       return res;
353     }
354
355     ///////////////////////////////////////////////////////////////////
356     namespace detail
357     { /////////////////////////////////////////////////////////////////
358       ///////////////////////////////////////////////////////////////////
359       //
360       //        CLASS NAME : SolvableIterator
361       //
362       /** */
363       class SolvableIterator : public boost::iterator_adaptor<
364           SolvableIterator                   // Derived
365           , detail::CSolvable*               // Base
366           , const Solvable                   // Value
367           , boost::forward_traversal_tag     // CategoryOrTraversal
368           , const Solvable                   // Reference
369           >
370       {
371         public:
372           SolvableIterator()
373           : SolvableIterator::iterator_adaptor_( 0 )
374           {}
375
376           explicit SolvableIterator( const Solvable & val_r )
377           : SolvableIterator::iterator_adaptor_( 0 )
378           { assignVal( val_r ); }
379
380           explicit SolvableIterator( SolvableIdType id_r )
381           : SolvableIterator::iterator_adaptor_( 0 )
382           { assignVal( Solvable( id_r ) ); }
383
384         private:
385           friend class boost::iterator_core_access;
386
387           Solvable dereference() const
388           { return _val; }
389
390           void increment()
391           { assignVal( _val.nextInPool() ); }
392
393         private:
394           void assignVal( const Solvable & val_r )
395           { _val = val_r; base_reference() = _val.get(); }
396
397           Solvable _val;
398       };
399       ///////////////////////////////////////////////////////////////////
400       /////////////////////////////////////////////////////////////////
401     } // namespace detail
402     ///////////////////////////////////////////////////////////////////
403
404     /////////////////////////////////////////////////////////////////
405   } // namespace sat
406   ///////////////////////////////////////////////////////////////////
407
408   /** \relates sat::Solvable Test whether a \ref sat::Solvable is of a certain Kind. */
409   template<class _Res>
410   inline bool isKind( const sat::Solvable & solvable_r )
411   { return solvable_r.isKind( ResTraits<_Res>::kind ); }
412
413   class PoolItem;
414   ///////////////////////////////////////////////////////////////////
415   namespace sat
416   { /////////////////////////////////////////////////////////////////
417     /** To Solvable transform functor.
418      * \relates Solvable
419      * \relates sat::SolvIterMixin
420      */
421     struct asSolvable
422     {
423       typedef Solvable result_type;
424
425       Solvable operator()( Solvable solv_r ) const
426       { return solv_r; }
427
428       Solvable operator()( const PoolItem & pi_r ) const;
429
430       Solvable operator()( const ResObject_constPtr & res_r ) const;
431     };
432     /////////////////////////////////////////////////////////////////
433   } // namespace sat
434   ///////////////////////////////////////////////////////////////////
435
436   /////////////////////////////////////////////////////////////////
437 } // namespace zypp
438 ///////////////////////////////////////////////////////////////////
439
440 ZYPP_DEFINE_ID_HASHABLE( ::zypp::sat::Solvable );
441
442 #endif // ZYPP_SAT_SOLVABLE_H