Imported Upstream version 15.19.0
[platform/upstream/libzypp.git] / zypp / ResStatus.h
index 17a33f8..499abc0 100644 (file)
 #ifndef ZYPP_RESSTATUS_H
 #define ZYPP_RESSTATUS_H
 
+#include <inttypes.h>
 #include <iosfwd>
-
 #include "zypp/Bit.h"
 
 ///////////////////////////////////////////////////////////////////
 namespace zypp
 { /////////////////////////////////////////////////////////////////
 
+  namespace resstatus
+  {
+    class UserLockQueryManip;
+    class StatusBackup;
+  }
+
   ///////////////////////////////////////////////////////////////////
   //
   //   CLASS NAME : ResStatus
@@ -27,13 +33,11 @@ namespace zypp
   /** Status bitfield.
    *
    * \li \c StateField Whether the resolvable is or uninstalled (available).
-   * \li \c EstablishField Established status computed by the solver as
-   *        unneeded (have freshens but none of them trigger)
-   *       satisfied (no freshen or at least one triggered freshen and
-   *       all requires fulfilled)
-   *       or incomplete (no freshen or at least one triggered freshen and
-   *       NOT all requires fulfilled)
-   * \li \c TransactField Wheter to transact this resolvable
+   * \li \c ValidateField Validate status computed by the solver as
+   *        nonrelevant: it is unimportant for the user
+   *       satisfied: it important nothing has to be done
+   *       broken: it is incomplete. So e.g. an update is needed
+   * \li \c TransactField Whether to transact this resolvable
    *        (delete if installed install if uninstalled).
    *        In case the resolvable is locked, only USER may modify the
    *        transact bit.
@@ -42,6 +46,8 @@ namespace zypp
    * \li \c TransactDetailField Reason why the Resolvable transacts.
    *        Splitted into \c InstallDetailValue and \c RemoveDetailValue
    *        dependent on the kind of transaction.
+   * \li \c WeakField The solvable will be recommended/suggested by
+   *        a to be installed/deleted solvable.
    *
   */
   class ResStatus
@@ -59,13 +65,14 @@ namespace zypp
     typedef uint16_t FieldType;
     typedef bit::BitField<FieldType> BitFieldType;
     // Bit Ranges within FieldType defined by 1st bit and size:
-    typedef bit::Range<FieldType,0,                        1> StateField;
-    typedef bit::Range<FieldType,StateField::end,          2> EstablishField;
-    typedef bit::Range<FieldType,EstablishField::end,      2> TransactField;
-    typedef bit::Range<FieldType,TransactField::end,       2> TransactByField;
-    typedef bit::Range<FieldType,TransactByField::end,     3> TransactDetailField;
-    typedef bit::Range<FieldType,TransactDetailField::end, 2> SolverStateField;
-    typedef bit::Range<FieldType,SolverStateField::end,    1> LicenceConfirmedField;
+    typedef bit::Range<FieldType,0,                          1> StateField;
+    typedef bit::Range<FieldType,StateField::end,            2> ValidateField;
+    typedef bit::Range<FieldType,ValidateField::end,         2> TransactField;
+    typedef bit::Range<FieldType,TransactField::end,         2> TransactByField;
+    typedef bit::Range<FieldType,TransactByField::end,       2> TransactDetailField;
+    typedef bit::Range<FieldType,TransactDetailField::end,   1> LicenceConfirmedField;
+    typedef bit::Range<FieldType,LicenceConfirmedField::end, 4> WeakField;
+    typedef bit::Range<FieldType,WeakField::end,             1> UserLockQueryField; // internal
     // enlarge FieldType if more bit's needed. It's not yet
     // checked by the compiler.
     //@}
@@ -83,12 +90,12 @@ namespace zypp
         UNINSTALLED = bit::RangeValue<StateField,0>::value,
         INSTALLED   = bit::RangeValue<StateField,1>::value
       };
-    enum EstablishValue
+    enum ValidateValue
       {
-        UNDETERMINED = bit::RangeValue<EstablishField,0>::value,
-        UNNEEDED     = bit::RangeValue<EstablishField,1>::value, // has freshens, none trigger
-        SATISFIED    = bit::RangeValue<EstablishField,2>::value, // has none or triggered freshens, all requirements fulfilled
-        INCOMPLETE   = bit::RangeValue<EstablishField,3>::value         // installed: has none or triggered freshens, requirements unfulfilled
+       UNDETERMINED = bit::RangeValue<ValidateField,0>::value,
+        BROKEN       = bit::RangeValue<ValidateField,1>::value,
+        SATISFIED    = bit::RangeValue<ValidateField,2>::value,
+        NONRELEVANT  = bit::RangeValue<ValidateField,3>::value
       };
     enum TransactValue
       {
@@ -109,7 +116,6 @@ namespace zypp
         /** Detail for no transact, i.e. reset any Install/RemoveDetailValue. */
         NO_DETAIL = bit::RangeValue<TransactDetailField,0>::value,
       };
-
     enum InstallDetailValue
       {
         EXPLICIT_INSTALL = bit::RangeValue<TransactDetailField,0>::value,
@@ -120,14 +126,7 @@ namespace zypp
         EXPLICIT_REMOVE = bit::RangeValue<TransactDetailField,0>::value,
        SOFT_REMOVE     = bit::RangeValue<TransactDetailField,1>::value,
         DUE_TO_OBSOLETE = bit::RangeValue<TransactDetailField,2>::value,
-        DUE_TO_UNLINK   = bit::RangeValue<TransactDetailField,3>::value,
-        DUE_TO_UPGRADE  = bit::RangeValue<TransactDetailField,4>::value
-      };
-    enum SolverStateValue
-      {
-       NORMAL     = bit::RangeValue<SolverStateField,0>::value, // default, notthing special
-       SEEN       = bit::RangeValue<SolverStateField,1>::value, // already seen during ResolverUpgrade
-       IMPOSSIBLE = bit::RangeValue<SolverStateField,2>::value  // impossible to install
+        DUE_TO_UPGRADE  = bit::RangeValue<TransactDetailField,3>::value
       };
 
     enum LicenceConfirmedValue
@@ -135,6 +134,21 @@ namespace zypp
         LICENCE_UNCONFIRMED = bit::RangeValue<LicenceConfirmedField,0>::value,
         LICENCE_CONFIRMED   = bit::RangeValue<LicenceConfirmedField,1>::value
       };
+
+    enum WeakValue     // Unlike the other fields those are BITS that may be or'ed!
+      {
+        NO_WEAK                = bit::RangeValue<WeakField,0>::value,
+        SUGGESTED              = bit::RangeValue<WeakField,1<<0>::value,
+       RECOMMENDED             = bit::RangeValue<WeakField,1<<1>::value,
+       ORPHANED                = bit::RangeValue<WeakField,1<<2>::value,
+       UNNEEDED                = bit::RangeValue<WeakField,1<<3>::value
+      };
+
+    enum UserLockQuery // internal
+      {
+        USERLOCK_NOMATCH       = bit::RangeValue<UserLockQueryField,0>::value,
+        USERLOCK_MATCH         = bit::RangeValue<UserLockQueryField,1>::value
+      };
     //@}
 
   public:
@@ -165,6 +179,50 @@ namespace zypp
     { fieldValueAssign<LicenceConfirmedField>( toVal_r ? LICENCE_CONFIRMED : LICENCE_UNCONFIRMED ); }
 
   public:
+    bool isRecommended() const
+    { return _bitfield.test( RECOMMENDED ); }
+
+    bool isSuggested() const
+    { return _bitfield.test( SUGGESTED ); }
+
+    bool isOrphaned() const
+    { return _bitfield.test( ORPHANED ); }
+
+    bool isUnneeded() const
+    { return _bitfield.test( UNNEEDED ); }
+
+    void resetWeak()
+    { return fieldValueAssign<WeakField>( NO_WEAK ); }
+
+    void setRecommended( bool toVal_r = true )
+    { _bitfield.set( RECOMMENDED, toVal_r ); }
+
+    void setSuggested( bool toVal_r = true )
+    { _bitfield.set( SUGGESTED, toVal_r ); }
+
+    void setOrphaned( bool toVal_r = true )
+    { _bitfield.set( ORPHANED, toVal_r ); }
+
+    void setUnneeded( bool toVal_r = true )
+    { _bitfield.set( UNNEEDED, toVal_r ); }
+
+  public:
+    ValidateValue validate() const
+    { return (ValidateValue)_bitfield.value<ValidateField>(); }
+
+    bool isUndetermined() const
+    { return fieldValueIs<ValidateField>( UNDETERMINED ); }
+
+    bool isSatisfied() const
+    { return fieldValueIs<ValidateField>( SATISFIED ); }
+
+    bool isBroken() const
+    { return fieldValueIs<ValidateField>( BROKEN ); }
+
+    bool isNonRelevant() const
+    { return fieldValueIs<ValidateField>( NONRELEVANT ); }
+
+  public:
     // These two are IMMUTABLE!
 
     bool isInstalled() const
@@ -191,35 +249,17 @@ namespace zypp
     bool isToBeUninstalled() const
     { return isInstalled() && transacts(); }
 
-    bool isUndetermined() const
-    { return fieldValueIs<EstablishField>( UNDETERMINED ); }
-
-    bool isEstablishedUneeded() const
-    { return fieldValueIs<EstablishField>( UNNEEDED ); }
-
-    bool isEstablishedSatisfied() const
-    { return fieldValueIs<EstablishField>( SATISFIED ); }
-
-    bool isEstablishedIncomplete() const
-    { return fieldValueIs<EstablishField>( INCOMPLETE ); }
-
-    bool isUnneeded() const
-    { return isUninstalled() && fieldValueIs<EstablishField>( UNNEEDED ); }
-
-    bool isSatisfied() const
-    { return isUninstalled() && fieldValueIs<EstablishField>( SATISFIED ); }
+    bool isLocked() const
+    { return fieldValueIs<TransactField>( LOCKED ); }
 
-    bool isComplete () const
-    { return isInstalled() && fieldValueIs<EstablishField>( SATISFIED ); }
+    bool isUserLocked() const
+    { return isLocked() && isByUser(); }
 
-    bool isIncomplete() const
-    { return isInstalled() && fieldValueIs<EstablishField>( INCOMPLETE ); }
+    bool isSoftLocked() const
+    { return isKept() && ( isByApplLow() || isByUser() ); }
 
-    bool isNeeded() const
-    { return isUninstalled() && fieldValueIs<EstablishField>( INCOMPLETE ); }
-
-    bool isLocked() const
-    { return fieldValueIs<TransactField>( LOCKED ); }
+    bool isKept() const
+    { return fieldValueIs<TransactField>( KEEP_STATE ); }
 
     bool transacts() const
     { return fieldValueIs<TransactField>( TRANSACT ); }
@@ -227,6 +267,14 @@ namespace zypp
     TransactValue getTransactValue() const
     { return (TransactValue)_bitfield.value<TransactField>(); }
 
+    /** True if would be on system after commit. */
+    bool onSystem() const
+    { return( isInstalled() != transacts() ); }
+
+    /** True if would be off system after commit. */
+    bool offSystem() const
+    { return ! onSystem(); }
+
     bool isBySolver() const
     { return fieldValueIs<TransactByField>( SOLVER ); }
 
@@ -242,21 +290,44 @@ namespace zypp
     TransactByValue getTransactByValue() const
     { return (TransactByValue)_bitfield.value<TransactByField>(); }
 
+    bool setTransactByValue(TransactByValue causer)
+    {
+       if ( isLessThan<TransactByField>( causer ) ) {
+           fieldValueAssign<TransactByField>( causer );
+           return true;
+       } else {
+           return false;
+       }
+    }
+
     bool isToBeUninstalledDueToObsolete () const
     { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_OBSOLETE ); }
 
-    bool isToBeUninstalledDueToUnlink() const
-    { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_UNLINK ); }
-
     bool isToBeUninstalledDueToUpgrade() const
     { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_UPGRADE ); }
 
     bool isToBeInstalledSoft () const
     { return isToBeInstalled() && fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
 
+    bool isToBeInstalledNotSoft () const
+    { return isToBeInstalled() && !fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
+
     bool isToBeUninstalledSoft () const
     { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( SOFT_REMOVE ); }
 
+  private:
+
+    /** \name Internal hard lock maintainance */
+    //@{
+    friend class resstatus::UserLockQueryManip;
+
+    bool isUserLockQueryMatch() const
+    { return fieldValueIs<UserLockQueryField>( USERLOCK_MATCH ); }
+
+    void setUserLockQueryMatch( bool match_r )
+    { fieldValueAssign<UserLockQueryField>( match_r ? USERLOCK_MATCH : USERLOCK_NOMATCH ); }
+    //@}
+
   public:
 
     //------------------------------------------------------------------------
@@ -298,9 +369,9 @@ namespace zypp
     }
 
     /** Apply a lock (prevent transaction).
-     * Currently by USER only, but who knows... Set LOCKED
-     * from KEEP_STATE to be shure all taransaction details
-     * were reset properly.
+     * Currently by USER or APPL_HIGH only, but who knows...
+     * Set LOCKED from KEEP_STATE to be shure all transaction
+     * details were reset properly.
     */
     bool setLock( bool toLock_r, TransactByValue causer_r )
     {
@@ -313,17 +384,24 @@ namespace zypp
            return true;
         }
       // Here: Lock status is to be changed:
-      if ( causer_r != USER )
-        return false;
-      // Setting no transact removes an existing lock,
-      // or brings this into KEEP_STATE, and we apply the lock.
-      if ( ! setTransact( false, causer_r ) )
+      if ( causer_r != USER && causer_r != APPL_HIGH )
         return false;
       if ( toLock_r ) {
-         fieldValueAssign<TransactField>( LOCKED );
-         fieldValueAssign<TransactByField>( causer_r );
-      } else
-         fieldValueAssign<TransactField>( KEEP_STATE );
+        // We're in unlocked state, which includes TRANSACT.
+        // Causer must be allowed to reset this. But from
+        // KEEP_STATE every causer is allowed to set the lock.
+        if ( ! setTransact( false, causer_r ) )
+          return false;
+        fieldValueAssign<TransactField>( LOCKED );
+        fieldValueAssign<TransactByField>( causer_r );
+      } else {
+        // To leave Locked state it needs a superior causer.
+        if ( isGreaterThan<TransactByField>( causer_r ) )
+          return false;
+        fieldValueAssign<TransactField>( KEEP_STATE );
+        fieldValueAssign<TransactByField>( SOLVER ); // reset to lowest causer
+                                                    // in order to distinguish from keep_state_by_user
+      }
       return true;
     }
 
@@ -347,27 +425,26 @@ namespace zypp
           // we're already in the desired state, but in case of
           // TRANSACT, remember a superior causer.
           if ( transacts() && isLessThan<TransactByField>( causer_r ) )
-            {
               fieldValueAssign<TransactByField>( causer_r );
-              // ??? adapt TransactDetailField ?
-            }
+
+         fieldValueAssign<TransactDetailField>( NO_DETAIL ); // Details has to be set again
           return true;
         }
       // Here: transact status is to be changed:
       if (    ! fieldValueIs<TransactField>( KEEP_STATE )
-           && isGreaterThan<TransactByField>( causer_r ) )
+             && isGreaterThan<TransactByField>( causer_r ) ) {
         return false;
+      }
 
       if ( toTansact_r )
-        {
+      {
           fieldValueAssign<TransactField>( TRANSACT );
-          // ??? adapt TransactDetailField ?
-        }
+      }
       else
-        {
+      {
           fieldValueAssign<TransactField>( KEEP_STATE );
-          fieldValueAssign<TransactDetailField>( NO_DETAIL );
-        }
+      }
+      fieldValueAssign<TransactDetailField>( NO_DETAIL ); // Details has to be set again
       fieldValueAssign<TransactByField>( causer_r );
       return true;
     }
@@ -380,6 +457,17 @@ namespace zypp
        return ret;
     }
 
+    /** */
+    bool setSoftLock( TransactByValue causer_r )
+    {
+      if ( ! setTransact( false, causer_r ) )
+        return false;
+      if ( fieldValueIs<TransactField>( KEEP_STATE )
+           && isLessThan<TransactByField>( causer_r ) )
+        fieldValueAssign<TransactByField>( causer_r );
+      return true;
+    }
+
     /** Not the same as setTransact( false ).
      */
     bool resetTransact( TransactByValue causer_r )
@@ -459,13 +547,6 @@ namespace zypp
     //------------------------------------------------------------------------
     // *** These are only for the Resolver ***
 
-    bool setToBeUninstalledDueToUnlink ( )
-    {
-      if (!setToBeUninstalled (SOLVER)) return false;
-      fieldValueAssign<TransactDetailField>(DUE_TO_UNLINK);
-      return true;
-    }
-
     bool setToBeUninstalledDueToObsolete ( )
     {
       if (!setToBeUninstalled (SOLVER)) return false;
@@ -482,18 +563,32 @@ namespace zypp
 
     bool setToBeInstalledSoft ( )
     {
-      if (!setToBeInstalled(SOLVER)) return false;
+      if (isInstalled()
+         || !setSoftTransact (true, SOLVER))
+         return false;
+
       fieldValueAssign<TransactDetailField>(SOFT_INSTALL);
       return true;
     }
 
     bool setToBeUninstalledSoft ( )
     {
-      if (!setToBeUninstalled(SOLVER)) return false;
+      if (!isInstalled()
+         || !setSoftTransact (true, SOLVER))
+         return false;
+
       fieldValueAssign<TransactDetailField>(SOFT_REMOVE);
       return true;
     }
 
+    bool maySetToBeUninstalledSoft ()
+    {
+       bit::BitField<FieldType> savBitfield = _bitfield;
+       bool ret = setToBeUninstalledSoft ();
+       _bitfield = savBitfield;
+       return ret;
+    }
+
     bool isSoftInstall () {
         return fieldValueIs<TransactDetailField> (SOFT_INSTALL);
     }
@@ -514,43 +609,25 @@ namespace zypp
 
     bool setUndetermined ()
     {
-      fieldValueAssign<EstablishField>(UNDETERMINED);
-      return true;
-    }
-
-    bool setUnneeded ()
-    {
-      fieldValueAssign<EstablishField>(UNNEEDED);
+      fieldValueAssign<ValidateField>(UNDETERMINED);
       return true;
     }
 
     bool setSatisfied ()
     {
-      fieldValueAssign<EstablishField>(SATISFIED);
+      fieldValueAssign<ValidateField>(SATISFIED);
       return true;
     }
 
-    bool setIncomplete ()
+    bool setBroken ()
     {
-      fieldValueAssign<EstablishField>(INCOMPLETE);
+      fieldValueAssign<ValidateField>(BROKEN);
       return true;
     }
 
-    bool isSeen () const
-    { return fieldValueIs<SolverStateField>( SEEN ); }
-
-    bool isImpossible () const
-    { return fieldValueIs<SolverStateField>( IMPOSSIBLE ); }
-
-    bool setSeen (bool value)
+    bool setNonRelevant ()
     {
-      fieldValueAssign<SolverStateField>( value ? SEEN : NORMAL );
-      return true;
-    }
-
-    bool setImpossible (bool value)
-    {
-      fieldValueAssign<SolverStateField>( value ? IMPOSSIBLE : NORMAL );
+      fieldValueAssign<ValidateField>(NONRELEVANT);
       return true;
     }
 
@@ -571,54 +648,43 @@ namespace zypp
     /** \name Builtin ResStatus constants. */
     //@{
     static const ResStatus toBeInstalled;
-    static const ResStatus toBeInstalledSoft;
     static const ResStatus toBeUninstalled;
-    static const ResStatus toBeUninstalledSoft;
-    static const ResStatus toBeUninstalledDueToUnlink;
-    static const ResStatus toBeUninstalledDueToObsolete;
     static const ResStatus toBeUninstalledDueToUpgrade;
-    static const ResStatus installed;  // installed, status after successful target 'install' commit
-    static const ResStatus uninstalled;        // uninstalled, status after successful target 'uninstall' commit
-    static const ResStatus satisfied;  // uninstalled, satisfied
-    static const ResStatus complete;   // installed, satisfied
-    static const ResStatus unneeded;   // uninstalled, unneeded
-    static const ResStatus needed;     // uninstalled, incomplete
-    static const ResStatus incomplete; // installed, incomplete
-    static const ResStatus impossible; // uninstallable
+    static const ResStatus toBeUninstalledDueToObsolete;
     //@}
 
   private:
     /** Ctor for intialization of builtin constants. */
     ResStatus( StateValue s,
-               EstablishValue e     = UNDETERMINED,
+               ValidateValue v      = UNDETERMINED,
                TransactValue t      = KEEP_STATE,
                InstallDetailValue i = EXPLICIT_INSTALL,
-               RemoveDetailValue r  = EXPLICIT_REMOVE,
-              SolverStateValue ssv = NORMAL );
+               RemoveDetailValue r  = EXPLICIT_REMOVE );
 
     /** Return whether the corresponding Field has value \a val_r.
     */
-    template<class _Field>
+    template<class TField>
       bool fieldValueIs( FieldType val_r ) const
-      { return _bitfield.isEqual<_Field>( val_r ); }
+    { return _bitfield.isEqual<TField>( val_r ); }
 
     /** Set the corresponding Field to value \a val_r.
     */
-    template<class _Field>
+    template<class TField>
       void fieldValueAssign( FieldType val_r )
-      { _bitfield.assign<_Field>( val_r ); }
+    { _bitfield.assign<TField>( val_r ); }
 
     /** compare two values.
     */
-    template<class _Field>
+    template<class TField>
       bool isGreaterThan( FieldType val_r )
-         { return _bitfield.value<_Field>() > val_r; }
+    { return _bitfield.value<TField>() > val_r; }
 
-    template<class _Field>
+    template<class TField>
       bool isLessThan( FieldType val_r )
-         { return _bitfield.value<_Field>() < val_r; }
+    { return _bitfield.value<TField>() < val_r; }
 
   private:
+    friend class resstatus::StatusBackup;
     BitFieldType _bitfield;
   };
   ///////////////////////////////////////////////////////////////////
@@ -626,6 +692,12 @@ namespace zypp
   /** \relates ResStatus Stream output */
   std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
 
+  /** \relates ResStatus Stream output */
+  std::ostream & operator<<( std::ostream & str, ResStatus::TransactValue obj );
+
+  /** \relates ResStatus Stream output */
+  std::ostream & operator<<( std::ostream & str, ResStatus::TransactByValue obj );
+
   /** \relates ResStatus */
   inline bool operator==( const ResStatus & lhs, const ResStatus & rhs )
   { return lhs._bitfield == rhs._bitfield; }
@@ -634,7 +706,32 @@ namespace zypp
   inline bool operator!=( const ResStatus & lhs, const ResStatus & rhs )
   { return ! (lhs == rhs); }
 
-  /////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////
+
+  namespace resstatus
+  {
+    class StatusBackup
+    {
+      public:
+        StatusBackup()
+        : _status( 0 )
+        {}
+
+        StatusBackup( ResStatus & status_r )
+        : _status( &status_r )
+        , _bitfield( _status->_bitfield )
+        {}
+
+        void replay()
+        { if ( _status ) _status->_bitfield = _bitfield; }
+
+      private:
+        ResStatus *             _status;
+        ResStatus::BitFieldType _bitfield;
+    };
+  }
+
+ /////////////////////////////////////////////////////////////////
 } // namespace zypp
 ///////////////////////////////////////////////////////////////////
 #endif // ZYPP_RESSTATUS_H