5b6ec7fa5f7b6a04f1e48abe7a3a33408c9ddeef
[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   class ByteCount;
32   class CheckSum;
33   class CpeId;
34   class Date;
35   class OnMediaLocation;
36   ///////////////////////////////////////////////////////////////////
37   namespace sat
38   {
39     ///////////////////////////////////////////////////////////////////
40     /// \class Solvable
41     /// \brief  A \ref Solvable object within the sat \ref Pool.
42     ///
43     /// \note Unfortunately libsolv combines the objects kind and
44     /// name in a single identifier \c "pattern:kde_multimedia",
45     /// \b except for packages and source packes. They are not prefixed
46     /// by any kind string. Instead the architecture is abused to store
47     /// \c "src" and \c "nosrc" values.
48     ///
49     /// \ref Solvable will hide this inconsistency by treating source
50     /// packages as an own kind of solvable and map their arch to
51     /// \ref Arch_noarch.
52     ///////////////////////////////////////////////////////////////////
53     class Solvable : protected detail::PoolMember
54     {
55     public:
56       typedef sat::detail::SolvableIdType IdType;
57
58     public:
59       /** Default ctor creates \ref noSolvable.*/
60       Solvable()
61       : _id( detail::noSolvableId )
62       {}
63
64       /** \ref PoolImpl ctor. */
65       explicit Solvable( IdType id_r )
66       : _id( id_r )
67       {}
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     public:
78       /** The identifier.
79        * This is the solvables \ref name, \b except for packages and
80        * source packes, prefixed by it's \ref kind.
81        */
82       IdString ident()const;
83
84       /** The Solvables ResKind. */
85       ResKind kind()const;
86
87       /** Test whether a Solvable is of a certain \ref ResKind.
88        * The test is far cheaper than actually retrieving and
89        * comparing the \ref kind.
90        */
91       bool isKind( const ResKind & kind_r ) const;
92       /** \overload */
93       template<class TRes>
94       bool isKind() const
95       { return isKind( resKind<TRes>() ); }
96       /** \overload Extend the test to a range of \ref ResKind. */
97       template<class TIterator>
98       bool isKind( TIterator begin, TIterator end ) const
99       { for_( it, begin, end ) if ( isKind( *it ) ) return true; return false; }
100
101       /** The name (without any ResKind prefix). */
102       std::string name() const;
103
104       /** The edition (version-release). */
105       Edition edition() const;
106
107       /** The architecture. */
108       Arch arch() const;
109
110       /** The vendor. */
111       IdString vendor() const;
112
113       /** The \ref Repository this \ref Solvable belongs to. */
114       Repository repository() const;
115       /** The repositories \ref RepoInfo. */
116       RepoInfo repoInfo() const;
117
118       /** Return whether this \ref Solvable belongs to the system repo.
119        * \note This includes the otherwise hidden systemSolvable.
120        */
121       bool isSystem() const;
122
123       /** Whether this is known to be installed on behalf of a user request.
124        * \note Returns \c false for non-system (uninstalled) solvables.
125        */
126       bool onSystemByUser() const;
127
128       /** Whether this is known to be automatically installed (as dependency of a user request package).
129        * \note Returns \c false for non-system (uninstalled) solvables.
130        */
131       bool onSystemByAuto() const;
132
133       /** Whether an installed solvable with the same \ref ident is flagged as AutoInstalled. */
134       bool identIsAutoInstalled() const
135       { return identIsAutoInstalled( ident() ); }
136       /** \overload static version */
137       static bool identIsAutoInstalled( const IdString & ident_r );
138
139       /** Whether this solvable triggers the reboot-needed hint if installed/updated. */
140       bool isNeedreboot() const;
141
142       /** Whether different versions of this package can be installed at the same time.
143        * Per default \c false. \see also \ref ZConfig::multiversion.
144        */
145       bool multiversionInstall() const;
146
147       /** The items build time. */
148       Date buildtime() const;
149
150       /** The items install time (\c false if not installed). */
151       Date installtime() const;
152
153     public:
154       /** String representation <tt>"ident-edition.arch"</tt> or \c "noSolvable"
155        * \code
156        *   product:openSUSE-11.1.x86_64
157        *   autoyast2-2.16.19-0.1.src
158        *   noSolvable
159        * \endcode
160        */
161       std::string asString() const;
162
163       /** String representation <tt>"ident-edition.arch(repo)"</tt> or \c "noSolvable" */
164       std::string asUserString() const;
165
166       /** Test whether two Solvables have the same content.
167        * Basically the same name, edition, arch, vendor and buildtime.
168        */
169       bool identical( const Solvable & rhs ) const;
170
171       /** Test for same name-version-release.arch */
172       bool sameNVRA( const Solvable & rhs ) const
173       { return( get() == rhs.get() || ( ident() == rhs.ident() && edition() == rhs.edition() && arch() == rhs.arch() ) ); }
174
175     public:
176       /** \name Access to the \ref Solvable dependencies.
177        *
178        * \note Prerequires are a subset of requires.
179        */
180       //@{
181       Capabilities provides()    const;
182       Capabilities requires()    const;
183       Capabilities conflicts()   const;
184       Capabilities obsoletes()   const;
185       Capabilities recommends()  const;
186       Capabilities suggests()    const;
187       Capabilities enhances()    const;
188       Capabilities supplements() const;
189       Capabilities prerequires() const;
190
191       /** Return \ref Capabilities selected by \ref Dep constant. */
192       Capabilities dep( Dep which_r ) const
193       {
194         switch( which_r.inSwitch() )
195         {
196           case Dep::PROVIDES_e:    return provides();    break;
197           case Dep::REQUIRES_e:    return requires();    break;
198           case Dep::CONFLICTS_e:   return conflicts();   break;
199           case Dep::OBSOLETES_e:   return obsoletes();   break;
200           case Dep::RECOMMENDS_e:  return recommends();  break;
201           case Dep::SUGGESTS_e:    return suggests();    break;
202           case Dep::ENHANCES_e:    return enhances();    break;
203           case Dep::SUPPLEMENTS_e: return supplements(); break;
204           case Dep::PREREQUIRES_e: return prerequires(); break;
205         }
206         return Capabilities();
207       }
208       /** \overload operator[] */
209       Capabilities operator[]( Dep which_r ) const
210       { return dep( which_r ); }
211
212
213       /** Return the namespaced provides <tt>'namespace([value])[ op edition]'</tt> of this Solvable. */
214       CapabilitySet providesNamespace( const std::string & namespace_r ) const;
215
216       /** Return <tt>'value[ op edition]'</tt> for namespaced provides <tt>'namespace(value)[ op edition]'</tt>.
217        * Similar to \ref providesNamespace, but the namespace is stripped from the
218        * dependencies. This is convenient if the namespace denotes packages that
219        * should be looked up. E.g. the \c weakremover namespace used in a products
220        * release package denotes the packages that were dropped from the distribution.
221        * \see \ref Product::droplist
222        */
223       CapabilitySet valuesOfNamespace( const std::string & namespace_r ) const;
224       //@}
225
226     public:
227       /** \name Locale support. */
228       //@{
229       /** Whether this \c Solvable claims to support locales. */
230       bool supportsLocales() const;
231       /** Whether this \c Solvable supports a specific \ref Locale. */
232       bool supportsLocale( const Locale & locale_r ) const;
233       /** Whether this \c Solvable supports at least one of the specified locales. */
234       bool supportsLocale( const LocaleSet & locales_r ) const;
235       /** Whether this \c Solvable supports at least one requested locale.
236        * \see \ref Pool::setRequestedLocales
237        */
238       bool supportsRequestedLocales() const;
239       /** Return the supported locales. */
240       LocaleSet getSupportedLocales() const;
241       /** \overload Legacy return via arg \a locales_r */
242       void getSupportedLocales( LocaleSet & locales_r ) const
243       { locales_r = getSupportedLocales(); }
244       //@}
245
246     public:
247       /** The solvables CpeId if available. */
248       CpeId cpeId() const;
249
250       /** Media number the solvable is located on (\c 0 if no media access required). */
251       unsigned mediaNr() const;
252
253       /** Installed (unpacked) size.
254        * This is just a total number. Many objects provide even more detailed
255        * disk usage data. You can use \ref DiskUsageCounter to find out
256        * how objects data are distributed across partitions/directories.
257        * \code
258        *   // Load directory set into ducounter
259        *   DiskUsageCounter ducounter( { "/", "/usr", "/var" } );
260        *
261        *   // see how noch space the packages use
262        *   for ( const PoolItem & pi : pool )
263        *   {
264        *     cout << pi << ducounter.disk_usage( pi ) << endl;
265        *     // I__s_(7)GeoIP-1.4.8-3.1.2.x86_64(@System) {
266        *     // dir:[/] [ bs: 0 B ts: 0 B us: 0 B (+-: 1.0 KiB)]
267        *     // dir:[/usr] [ bs: 0 B ts: 0 B us: 0 B (+-: 133.0 KiB)]
268        *     // dir:[/var] [ bs: 0 B ts: 0 B us: 0 B (+-: 1.1 MiB)]
269        *     // }
270        *   }
271        * \endcode
272        * \see \ref DiskUsageCounter
273        */
274       ByteCount installSize() const;
275
276       /** Download size. */
277       ByteCount downloadSize() const;
278
279       /** The distribution string. */
280       std::string distribution() const;
281
282       /** Short (singleline) text describing the solvable (opt. translated). */
283       std::string summary( const Locale & lang_r = Locale() ) const;
284
285       /** Long (multiline) text describing the solvable (opt. translated). */
286       std::string description( const Locale & lang_r = Locale() ) const;
287
288       /** UI hint text when selecting the solvable for install (opt. translated). */
289       std::string insnotify( const Locale & lang_r = Locale() ) const;
290       /** UI hint text when selecting the solvable for uninstall (opt. translated).*/
291       std::string delnotify( const Locale & lang_r = Locale() ) const;
292
293       /** License or agreement to accept before installing the solvable (opt. translated). */
294       std::string licenseToConfirm( const Locale & lang_r = Locale() ) const;
295       /** \c True except for well known exceptions (i.e show license but no need to accept it). */
296       bool needToAcceptLicense() const;
297
298     public:
299       /** Helper that splits an identifier into kind and name or vice versa.
300        * \note In case \c name_r is preceded by a well known kind spec, the
301        * \c kind_r argument is ignored, and kind is derived from name.
302        * \see \ref ident
303        */
304       class SplitIdent
305       {
306       public:
307         SplitIdent() {}
308         SplitIdent( IdString ident_r );
309         SplitIdent( const char * ident_r );
310         SplitIdent( const std::string & ident_r );
311         SplitIdent( ResKind kind_r, IdString name_r );
312         SplitIdent( ResKind kind_r, const C_Str & name_r );
313
314         IdString ident() const { return _ident; }
315         ResKind  kind()  const { return _kind; }
316         IdString name()  const { return _name; }
317
318       private:
319         IdString  _ident;
320         ResKind   _kind;
321         IdString  _name;
322       };
323
324     public:
325       /** \name Attribute lookup.
326        * \see \ref LookupAttr and  \ref ArrayAttr providing a general, more
327        * query like interface for attribute retrieval.
328        */
329       //@{
330       /**
331        * returns the string attribute value for \ref attr
332        * or an empty string if it does not exists.
333        */
334       std::string lookupStrAttribute( const SolvAttr & attr ) const;
335       /** \overload Trying to look up a translated string attribute.
336        *
337        * Returns the translation for \c lang_r.
338        *
339        * Passing an empty \ref Locale will return the string for the
340        * current default locale (\see \ref ZConfig::TextLocale),
341        * \b considering all fallback locales.
342        *
343        * Returns an empty string if no translation is available.
344        */
345       std::string lookupStrAttribute( const SolvAttr & attr, const Locale & lang_r ) const;
346
347       /**
348        * returns the numeric attribute value for \ref attr
349        * or 0 if it does not exists.
350        */
351       unsigned long long lookupNumAttribute( const SolvAttr & attr ) const;
352       /** \overload returning custom notfound_r value */
353       unsigned long long lookupNumAttribute( const SolvAttr & attr, unsigned long long notfound_r ) const;
354
355       /**
356        * returns the boolean attribute value for \ref attr
357        * or \c false if it does not exists.
358        */
359       bool lookupBoolAttribute( const SolvAttr & attr ) const;
360
361       /**
362        * returns the id attribute value for \ref attr
363        * or \ref detail::noId if it does not exists.
364        */
365       detail::IdType lookupIdAttribute( const SolvAttr & attr ) const;
366
367       /**
368        * returns the CheckSum attribute value for \ref attr
369        * or an empty CheckSum if ir does not exist.
370        */
371       CheckSum lookupCheckSumAttribute( const SolvAttr & attr ) const;
372
373       /**
374        * returns OnMediaLocation data: This is everything we need to
375        * download e.g. an rpm (path, checksum, downloadsize, etc.).
376        */
377       OnMediaLocation lookupLocation() const;
378       //@}
379
380     public:
381       /** Return next Solvable in \ref Pool (or \ref noSolvable). */
382       Solvable nextInPool() const;
383       /** Return next Solvable in \ref Repo (or \ref noSolvable). */
384       Solvable nextInRepo() const;
385       /** Expert backdoor. */
386       detail::CSolvable * get() const;
387       /** Expert backdoor. */
388       IdType id() const { return _id; }
389
390     private:
391       IdType _id;
392     };
393     ///////////////////////////////////////////////////////////////////
394
395     /** \relates Solvable Stream output */
396     std::ostream & operator<<( std::ostream & str, const Solvable & obj );
397
398     /** \relates Solvable More verbose stream output including dependencies */
399     std::ostream & dumpOn( std::ostream & str, const Solvable & obj );
400
401     /** \relates Solvable XML output */
402     std::ostream & dumpAsXmlOn( std::ostream & str, const Solvable & obj );
403
404     /** \relates Solvable */
405     inline bool operator==( const Solvable & lhs, const Solvable & rhs )
406     { return lhs.get() == rhs.get(); }
407
408     /** \relates Solvable */
409     inline bool operator!=( const Solvable & lhs, const Solvable & rhs )
410     { return lhs.get() != rhs.get(); }
411
412     /** \relates Solvable */
413     inline bool operator<( const Solvable & lhs, const Solvable & rhs )
414     { return lhs.get() < rhs.get(); }
415
416     /** \relates Solvable Test whether a \ref Solvable is of a certain Kind. */
417     template<class TRes>
418     inline bool isKind( const Solvable & solvable_r )
419     { return solvable_r.isKind( ResTraits<TRes>::kind ); }
420
421     /** \relates Solvable Test for same content. */
422     inline bool identical( const Solvable & lhs, const Solvable & rhs )
423     { return lhs.identical( rhs ); }
424
425     /** \relates Solvable Test for same name version release and arch. */
426     inline bool sameNVRA( const Solvable & lhs, const Solvable & rhs )
427     { return lhs.sameNVRA( rhs ); }
428
429
430     /** \relates Solvable Compare according to \a kind and \a name. */
431     inline int compareByN( const Solvable & lhs, const Solvable & rhs )
432     {
433       int res = 0;
434       if ( lhs != rhs )
435       {
436         if ( (res = lhs.kind().compare( rhs.kind() )) == 0 )
437           res = lhs.name().compare( rhs.name() );
438       }
439       return res;
440     }
441
442     /** \relates Solvable Compare according to \a kind, \a name and \a edition. */
443     inline int compareByNVR( const Solvable & lhs, const Solvable & rhs )
444     {
445       int res = compareByN( lhs, rhs );
446       if ( res == 0 )
447         res = lhs.edition().compare( rhs.edition() );
448       return res;
449     }
450
451     /** \relates Solvable Compare according to \a kind, \a name, \a edition and \a arch. */
452     inline int compareByNVRA( const Solvable & lhs, const Solvable & rhs )
453     {
454       int res = compareByNVR( lhs, rhs );
455       if ( res == 0 )
456         res = lhs.arch().compare( rhs.arch() );
457       return res;
458     }
459
460     ///////////////////////////////////////////////////////////////////
461     namespace detail
462     {
463       ///////////////////////////////////////////////////////////////////
464       //
465       //        CLASS NAME : SolvableIterator
466       //
467       /** */
468       class SolvableIterator : public boost::iterator_adaptor<
469           SolvableIterator                   // Derived
470           , CSolvable*                       // Base
471           , const Solvable                   // Value
472           , boost::forward_traversal_tag     // CategoryOrTraversal
473           , const Solvable                   // Reference
474           >
475       {
476         public:
477           SolvableIterator()
478           : SolvableIterator::iterator_adaptor_( 0 )
479           {}
480
481           explicit SolvableIterator( const Solvable & val_r )
482           : SolvableIterator::iterator_adaptor_( 0 )
483           { assignVal( val_r ); }
484
485           explicit SolvableIterator( SolvableIdType id_r )
486           : SolvableIterator::iterator_adaptor_( 0 )
487           { assignVal( Solvable( id_r ) ); }
488
489         private:
490           friend class boost::iterator_core_access;
491
492           Solvable dereference() const
493           { return _val; }
494
495           void increment()
496           { assignVal( _val.nextInPool() ); }
497
498         private:
499           void assignVal( const Solvable & val_r )
500           { _val = val_r; base_reference() = _val.get(); }
501
502           Solvable _val;
503       };
504     } // namespace detail
505     ///////////////////////////////////////////////////////////////////
506   } // namespace sat
507   ///////////////////////////////////////////////////////////////////
508
509   class PoolItem;
510   ///////////////////////////////////////////////////////////////////
511   namespace sat
512   {
513     /** To Solvable transform functor.
514      * \relates Solvable
515      * \relates sat::SolvIterMixin
516      */
517     struct asSolvable
518     {
519       typedef Solvable result_type;
520
521       Solvable operator()( const Solvable & solv_r ) const
522       { return solv_r; }
523
524       Solvable operator()( const PoolItem & pi_r ) const;
525
526       Solvable operator()( const ResObject_constPtr & res_r ) const;
527     };
528   } // namespace sat
529   ///////////////////////////////////////////////////////////////////
530 } // namespace zypp
531 ///////////////////////////////////////////////////////////////////
532
533 ZYPP_DEFINE_ID_HASHABLE( ::zypp::sat::Solvable );
534
535 #endif // ZYPP_SAT_SOLVABLE_H