Imported Upstream version 15.10.0
[platform/upstream/libzypp.git] / zypp / sat / Transaction.cc
index c57b4b0..d351aa4 100644 (file)
  */
 extern "C"
 {
-#include <satsolver/transaction.h>
+#include <solv/transaction.h>
+#include <solv/solver.h>
 }
 #include <iostream>
 #include "zypp/base/LogTools.h"
 #include "zypp/base/SerialNumber.h"
 #include "zypp/base/DefaultIntegral.h"
 #include "zypp/base/NonCopyable.h"
-#include "zypp/base/Tr1hash.h"
+#include "zypp/base/Hash.h"
 
 #include "zypp/sat/detail/PoolImpl.h"
 #include "zypp/sat/Transaction.h"
 #include "zypp/sat/Solvable.h"
 #include "zypp/sat/Queue.h"
-#include "zypp/PoolItem.h"
+#include "zypp/sat/Map.h"
+#include "zypp/ResPool.h"
 
 using std::endl;
 
@@ -43,12 +45,13 @@ namespace zypp
      *
      */
     struct Transaction::Impl : protected detail::PoolMember
+                            , private base::NonCopyable
     {
       friend std::ostream & operator<<( std::ostream & str, const Impl & obj );
 
       public:
-       typedef std::tr1::unordered_set<detail::IdType> set_type;
-       typedef std::tr1::unordered_map<detail::IdType,detail::IdType> map_type;
+       typedef std::unordered_set<detail::IdType> set_type;
+       typedef std::unordered_map<detail::IdType,detail::IdType> map_type;
 
        struct PostMortem
        {
@@ -64,21 +67,40 @@ namespace zypp
          Edition  _edition;
          Arch     _arch;
        };
-       typedef std::tr1::unordered_map<detail::IdType,PostMortem> pmmap_type;
+       typedef std::unordered_map<detail::IdType,PostMortem> pmmap_type;
 
       public:
        Impl()
-       { memset( &_trans, 0, sizeof(_trans) ); }
+         : _trans( ::transaction_create( nullptr ) )
+       { memset( _trans, 0, sizeof(*_trans) ); }
 
-       Impl( ::_Transaction & trans_r )
-         : _watcher(  myPool().serial() )
+       Impl( LoadFromPoolType )
+         : _watcher( myPool().serial() )
+         , _trans( nullptr )
        {
-         ::transaction_init_clone( &_trans, &trans_r );
+         Queue decisionq;
+         for_( it, ResPool::instance().begin(), ResPool::instance().end() )
+         {
+           if ( ! (*it).status().transacts() )
+             continue;
+           sat::Solvable solv( (*it).satSolvable() );
+           decisionq.push( solv.isSystem() ? -solv.id() : solv.id() );
+         }
+         Queue noobsq;
+         for_( it, sat::Pool::instance().multiversionBegin(), sat::Pool::instance().multiversionEnd() )
+         {
+           noobsq.push( SOLVER_NOOBSOLETES | SOLVER_SOLVABLE_NAME );
+           noobsq.push( it->id() );
+         }
+         Map noobsmap;
+         ::solver_calculate_noobsmap( myPool().getPool(), noobsq, noobsmap );
+         _trans = ::transaction_create_decisionq( myPool().getPool(), decisionq, noobsmap );
+
          // NOTE: package/product buddies share the same ResStatus
          // so we also link the buddies stepStages. This assumes
          // only one buddy is acting during commit (package is installed,
          // but no extra operation for the product).
-         for_( it, _trans.steps.elements, _trans.steps.elements + _trans.steps.count )
+         for_( it, _trans->steps.elements, _trans->steps.elements + _trans->steps.count )
          {
            sat::Solvable solv( *it );
            // buddy list:
@@ -104,7 +126,7 @@ namespace zypp
        }
 
        ~Impl()
-       { ::transaction_free( &_trans ); }
+       { ::transaction_free( _trans ); }
 
       public:
        bool valid() const
@@ -114,17 +136,19 @@ namespace zypp
        {
          if ( ! valid() )
            return false;
+         if ( empty() )
+           return true;
 #if 0
          // This is hwo we could implement out own order method.
          // As ::transaction already groups by MediaNr, we don't
          // need it for ORDER_BY_MEDIANR.
-         ::transaction_order( &_trans, SOLVER_TRANSACTION_KEEP_ORDERDATA );
+         ::transaction_order( _trans, SOLVER_TRANSACTION_KEEP_ORDERDATA );
          detail::IdType chosen = 0;
          Queue choices;
 
          while ( true )
          {
-           int ret = transaction_order_add_choices( &_trans, chosen, choices );
+           int ret = transaction_order_add_choices( _trans, chosen, choices );
            MIL << ret << ": " << chosen << ": " << choices << endl;
            chosen = choices.pop_front(); // pick one out of choices
            if ( ! chosen )
@@ -134,27 +158,27 @@ namespace zypp
 #endif
          if ( !_ordered )
          {
-           ::transaction_order( &_trans, 0 );
+           ::transaction_order( _trans, 0 );
            _ordered = true;
          }
          return true;
        }
 
        bool empty() const
-       { return( _trans.steps.count == 0 ); }
+       { return( _trans->steps.count == 0 ); }
 
        size_t size() const
-       { return _trans.steps.count; }
+       { return _trans->steps.count; }
 
        const_iterator begin( const RW_pointer<Transaction::Impl> & self_r ) const
-       { return const_iterator( self_r, _trans.steps.elements ); }
+       { return const_iterator( self_r, _trans->steps.elements ); }
        iterator begin( const RW_pointer<Transaction::Impl> & self_r )
-       { return iterator( self_r, _trans.steps.elements ); }
+       { return iterator( self_r, _trans->steps.elements ); }
 
        const_iterator end( const RW_pointer<Transaction::Impl> & self_r ) const
-       { return const_iterator( self_r, _trans.steps.elements + _trans.steps.count ); }
+       { return const_iterator( self_r, _trans->steps.elements + _trans->steps.count ); }
        iterator end( const RW_pointer<Transaction::Impl> & self_r )
-       { return iterator( self_r, _trans.steps.elements + _trans.steps.count ); }
+       { return iterator( self_r, _trans->steps.elements + _trans->steps.count ); }
 
        const_iterator find(const RW_pointer<Transaction::Impl> & self_r, const sat::Solvable & solv_r ) const
        { detail::IdType * it( _find( solv_r ) ); return it ? const_iterator( self_r, it ) : end( self_r ); }
@@ -162,6 +186,16 @@ namespace zypp
        { detail::IdType * it( _find( solv_r ) ); return it ? iterator( self_r, it ) : end( self_r ); }
 
       public:
+       int installedResult( Queue & result_r ) const
+       { return ::transaction_installedresult( _trans, result_r ); }
+
+       StringQueue autoInstalled() const
+       { return _autoInstalled; }
+
+       void autoInstalled( const StringQueue & queue_r )
+       { _autoInstalled = queue_r; }
+
+      public:
        StepType stepType( Solvable solv_r ) const
        {
          if ( ! solv_r )
@@ -170,7 +204,7 @@ namespace zypp
            return isIn( _systemErase, solv_r.id() ) ? TRANSACTION_ERASE : TRANSACTION_IGNORE;
          }
 
-         switch( ::transaction_type( &_trans, solv_r.id(), SOLVER_TRANSACTION_RPM_ONLY ) )
+         switch( ::transaction_type( _trans, solv_r.id(), SOLVER_TRANSACTION_RPM_ONLY ) )
          {
            case SOLVER_TRANSACTION_ERASE: return TRANSACTION_ERASE; break;
            case SOLVER_TRANSACTION_INSTALL: return TRANSACTION_INSTALL; break;
@@ -231,9 +265,9 @@ namespace zypp
       private:
        detail::IdType * _find( const sat::Solvable & solv_r ) const
        {
-         if ( solv_r && _trans.steps.elements )
+         if ( solv_r && _trans->steps.elements )
          {
-           for_( it, _trans.steps.elements, _trans.steps.elements + _trans.steps.count )
+           for_( it, _trans->steps.elements, _trans->steps.elements + _trans->steps.count )
            {
              if ( *it == detail::IdType(solv_r.id()) )
                return it;
@@ -244,7 +278,7 @@ namespace zypp
 
      private:
        SerialNumberWatcher _watcher;
-       mutable ::Transaction _trans;
+       mutable ::Transaction _trans;
        DefaultIntegral<bool,false> _ordered;
        //
        set_type        _doneSet;
@@ -253,6 +287,8 @@ namespace zypp
        set_type        _systemErase;   // @System packages to be eased (otherse are TRANSACTION_IGNORE)
        pmmap_type      _pmMap;         // Post mortem data of deleted @System solvables
 
+       StringQueue     _autoInstalled; // ident strings of all packages that would be auto-installed after the transaction is run.
+
       public:
         /** Offer default Impl. */
         static shared_ptr<Impl> nullimpl()
@@ -278,8 +314,8 @@ namespace zypp
       : _pimpl( Impl::nullimpl() )
     {}
 
-    Transaction::Transaction( ::_Transaction & trans_r )
-      : _pimpl( new Impl( trans_r ) )
+    Transaction::Transaction( LoadFromPoolType )
+      : _pimpl( new Impl( loadFromPool ) )
     {}
 
     Transaction::~Transaction()
@@ -315,6 +351,15 @@ namespace zypp
     Transaction::iterator Transaction::find( const sat::Solvable & solv_r )
     { return _pimpl->find( _pimpl, solv_r ); }
 
+    int Transaction::installedResult( Queue & result_r ) const
+    { return _pimpl->installedResult( result_r ); }
+
+    StringQueue Transaction::autoInstalled() const
+    { return _pimpl->autoInstalled(); }
+
+    void Transaction::autoInstalled( const StringQueue & queue_r )
+    { _pimpl->autoInstalled( queue_r ); }
+
     std::ostream & operator<<( std::ostream & str, const Transaction & obj )
     { return str << *obj._pimpl; }