Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / PoolItem.cc
index 40076df..44aae33 100644 (file)
  *
 */
 #include <iostream>
-//#include "zypp/base/Logger.h"
+#include "zypp/base/Logger.h"
+#include "zypp/base/DefaultIntegral.h"
 
 #include "zypp/PoolItem.h"
+#include "zypp/ResPool.h"
+#include "zypp/Package.h"
+#include "zypp/VendorAttr.h"
 
 using std::endl;
 
@@ -24,31 +28,145 @@ namespace zypp
   //
   //   CLASS NAME : PoolItem::Impl
   //
-  /** PoolItem implementation. */
+  /** PoolItem implementation.
+   * \c _buddy handling:
+   * \li \c ==0 no buddy
+   * \li \c >0 this uses \c _buddy status
+   * \li \c <0 this status used by \c -_buddy
+   */
   struct PoolItem::Impl
   {
-    Impl( ResObject::constPtr res_r,
-          const ResStatus & status_r = ResStatus() )
-    : _status( status_r )
-    , _resolvable( res_r )
-    {}
+    public:
+      Impl() {}
 
-    ResStatus & status() const
-    { return _status; }
+      Impl( ResObject::constPtr res_r,
+            const ResStatus & status_r )
+      : _status( status_r )
+      , _resolvable( res_r )
+      {}
 
-    ResObject::constPtr resolvable() const
-    { return _resolvable; }
+      ResStatus & status() const
+      { return _buddy > 0 ? PoolItem(buddy()).status() : _status; }
 
-  private:
-    mutable ResStatus   _status;
-    ResObject::constPtr _resolvable;
+      sat::Solvable buddy() const
+      {
+        if ( !_buddy )
+          return sat::Solvable::noSolvable;
+        if ( _buddy < 0 )
+          return sat::Solvable( -_buddy );
+        return sat::Solvable( _buddy );
+      }
+
+      void setBuddy( sat::Solvable solv_r );
+
+      ResObject::constPtr resolvable() const
+      { return _resolvable; }
+
+      ResStatus & statusReset() const
+      {
+        _status.setLock( false, zypp::ResStatus::USER );
+        _status.resetTransact( zypp::ResStatus::USER );
+        return _status;
+      }
+
+    public:
+      bool isUndetermined() const
+      {
+         return status().isUndetermined();
+      }
+
+      bool isRelevant() const
+      {
+         return !status().isNonRelevant();
+      }
+
+      bool isSatisfied() const
+      {
+         return status().isSatisfied();
+      }
+
+      bool isBroken() const
+      {
+         return status().isBroken();
+      }
+
+      bool isNeeded() const
+      {
+       return status().isToBeInstalled() || ( isBroken() && ! status().isLocked() );
+      }
+
+      bool isUnwanted() const
+      {
+       return isBroken() && status().isLocked();
+      }
+
+    private:
+      mutable ResStatus     _status;
+      ResObject::constPtr   _resolvable;
+      DefaultIntegral<sat::detail::IdType,sat::detail::noId> _buddy;
+
+    /** \name Poor man's save/restore state.
+       * \todo There may be better save/restore state strategies.
+     */
+    //@{
+    public:
+      void saveState() const
+      { _savedStatus = status(); }
+      void restoreState() const
+      { status() = _savedStatus; }
+      bool sameState() const
+      {
+        if ( status() == _savedStatus )
+          return true;
+        // some bits changed...
+        if ( status().getTransactValue() != _savedStatus.getTransactValue()
+             && ( ! status().isBySolver() // ignore solver state changes
+                  // removing a user lock also goes to bySolver
+                  || _savedStatus.getTransactValue() == ResStatus::LOCKED ) )
+          return false;
+        if ( status().isLicenceConfirmed() != _savedStatus.isLicenceConfirmed() )
+          return false;
+        return true;
+      }
+    private:
+      mutable ResStatus _savedStatus;
+    //@}
+
+    public:
+      /** Offer default Impl. */
+      static shared_ptr<Impl> nullimpl()
+      {
+        static shared_ptr<Impl> _nullimpl( new Impl );
+        return _nullimpl;
+      }
   };
   ///////////////////////////////////////////////////////////////////
 
   /** \relates PoolItem::Impl Stream output */
   inline std::ostream & operator<<( std::ostream & str, const PoolItem::Impl & obj )
   {
-    return str << obj.status() << *obj.resolvable();
+    str << obj.status();
+    if (obj.resolvable())
+       str << *obj.resolvable();
+    else
+       str << "(NULL)";
+    return str;
+  }
+
+  inline void PoolItem::Impl::setBuddy( sat::Solvable solv_r )
+  {
+    PoolItem myBuddy( solv_r );
+    if ( myBuddy )
+    {
+      if ( myBuddy._pimpl->_buddy )
+      {
+       ERR <<  *this << " would be buddy2 in " << myBuddy << endl;
+       return;
+      }
+      myBuddy._pimpl->_buddy = -resolvable()->satSolvable().id();
+      _buddy = myBuddy.satSolvable().id();
+      DBG << *this << " has buddy " << myBuddy << endl;
+    }
   }
 
   ///////////////////////////////////////////////////////////////////
@@ -63,6 +181,16 @@ namespace zypp
   //   METHOD TYPE : Ctor
   //
   PoolItem::PoolItem()
+  : _pimpl( Impl::nullimpl() )
+  {}
+
+  ///////////////////////////////////////////////////////////////////
+  //
+  //   METHOD NAME : PoolItem::PoolItem
+  //   METHOD TYPE : Ctor
+  //
+  PoolItem::PoolItem( const sat::Solvable & solvable_r )
+  : _pimpl( ResPool::instance().find( solvable_r )._pimpl )
   {}
 
   ///////////////////////////////////////////////////////////////////
@@ -70,8 +198,8 @@ namespace zypp
   //   METHOD NAME : PoolItem::PoolItem
   //   METHOD TYPE : Ctor
   //
-  PoolItem::PoolItem( ResObject::constPtr res_r )
-  : _pimpl( new Impl( res_r ) )
+  PoolItem::PoolItem( const ResObject::constPtr & resolvable_r )
+  : _pimpl( ResPool::instance().find( resolvable_r )._pimpl )
   {}
 
   ///////////////////////////////////////////////////////////////////
@@ -79,12 +207,22 @@ namespace zypp
   //   METHOD NAME : PoolItem::PoolItem
   //   METHOD TYPE : Ctor
   //
-  PoolItem::PoolItem( ResObject::constPtr res_r, const ResStatus & status_r )
-  : _pimpl( new Impl( res_r, status_r ) )
+  PoolItem::PoolItem( Impl * implptr_r )
+  : _pimpl( implptr_r )
   {}
 
   ///////////////////////////////////////////////////////////////////
   //
+  //   METHOD NAME : PoolItem::makePoolItem
+  //   METHOD TYPE : PoolItem
+  //
+  PoolItem PoolItem::makePoolItem( const sat::Solvable & solvable_r )
+  {
+    return PoolItem( new Impl( makeResObject( solvable_r ), solvable_r.isSystem() ) );
+  }
+
+  ///////////////////////////////////////////////////////////////////
+  //
   //   METHOD NAME : PoolItem::~PoolItem
   //   METHOD TYPE : Dtor
   //
@@ -93,6 +231,14 @@ namespace zypp
 
   ///////////////////////////////////////////////////////////////////
   //
+  //   METHOD NAME : PoolItem::pool
+  //   METHOD TYPE : ResPool
+  //
+  ResPool PoolItem::pool() const
+  { return ResPool::instance(); }
+
+  ///////////////////////////////////////////////////////////////////
+  //
   //   Forward to Impl:
   //
   ///////////////////////////////////////////////////////////////////
@@ -100,6 +246,42 @@ namespace zypp
   ResStatus & PoolItem::status() const
   { return _pimpl->status(); }
 
+  ResStatus & PoolItem::statusReset() const
+  { return _pimpl->statusReset(); }
+
+  sat::Solvable PoolItem::buddy() const
+  { return _pimpl->buddy(); }
+
+  void PoolItem::setBuddy( sat::Solvable solv_r )
+  { _pimpl->setBuddy( solv_r ); }
+
+  bool PoolItem::isUndetermined() const
+  { return _pimpl->isUndetermined(); }
+
+  bool PoolItem::isRelevant() const
+  { return _pimpl->isRelevant(); }
+
+  bool PoolItem::isSatisfied() const
+  { return _pimpl->isSatisfied(); }
+
+  bool PoolItem::isBroken() const
+  { return _pimpl->isBroken(); }
+
+  bool PoolItem::isNeeded() const
+  { return _pimpl->isNeeded(); }
+
+  bool PoolItem::isUnwanted() const
+  { return _pimpl->isUnwanted(); }
+
+  void PoolItem::saveState() const
+  { _pimpl->saveState(); }
+
+  void PoolItem::restoreState() const
+  { _pimpl->restoreState(); }
+
+  bool PoolItem::sameState() const
+  { return _pimpl->sameState(); }
+
   ResObject::constPtr PoolItem::resolvable() const
   { return _pimpl->resolvable(); }