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