Add class satTransaction (satsolver transaction wrapper).
authorMichael Andres <ma@suse.de>
Wed, 18 May 2011 12:20:00 +0000 (14:20 +0200)
committerMichael Andres <ma@suse.de>
Tue, 31 May 2011 15:23:40 +0000 (17:23 +0200)
zypp/CMakeLists.txt
zypp/Resolver.cc
zypp/Resolver.h
zypp/sat/Transaction.cc [new file with mode: 0644]
zypp/sat/Transaction.h [new file with mode: 0644]
zypp/solver/detail/Resolver.cc
zypp/solver/detail/Resolver.h
zypp/solver/detail/SATResolver.cc
zypp/solver/detail/SATResolver.h

index 83f0386..9a98046 100644 (file)
@@ -530,6 +530,7 @@ SET( zypp_sat_SRCS
   sat/Solvable.cc
   sat/SolvableSet.cc
   sat/SolvIterMixin.cc
+  sat/Transaction.cc
   sat/WhatProvides.cc
   sat/WhatObsoletes.cc
   sat/LocaleSupport.cc
@@ -543,6 +544,7 @@ SET( zypp_sat_HEADERS
   sat/Solvable.h
   sat/SolvableSet.h
   sat/SolvIterMixin.h
+  sat/Transaction.h
   sat/WhatProvides.h
   sat/WhatObsoletes.h
   sat/LocaleSupport.h
index ad1fe4a..9922788 100644 (file)
@@ -16,6 +16,7 @@
 #include "zypp/TriBool.h"
 #include "zypp/solver/detail/Resolver.h"
 #include "zypp/solver/detail/Testcase.h"
+#include "zypp/sat/Transaction.h"
 
 using namespace std;
 
@@ -67,6 +68,9 @@ namespace zypp
   void Resolver::applySolutions( const ProblemSolutionList & solutions )
   { _pimpl->applySolutions (solutions); }
 
+  sat::Transaction Resolver::getTransaction()
+  { return _pimpl->getTransaction(); }
+
   bool Resolver::doUpgrade()
   { return _pimpl->doUpgrade(); }
 
index 4ad256b..f76a331 100644 (file)
 namespace zypp
 { /////////////////////////////////////////////////////////////////
 
+  namespace sat
+  {
+    class Transaction;
+  }
 
   ///////////////////////////////////////////////////////////////////
   //
@@ -154,6 +158,10 @@ namespace zypp
      **/
     void applySolutions( const ProblemSolutionList & solutions );
 
+    /**
+     * Return the \ref Transaction computed by the last solver run.
+     */
+    sat::Transaction getTransaction();
 
     /**
      * Remove resolvables which are conflicts with others or
diff --git a/zypp/sat/Transaction.cc b/zypp/sat/Transaction.cc
new file mode 100644 (file)
index 0000000..99ece4d
--- /dev/null
@@ -0,0 +1,377 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp/sat/Transaction.cc
+ */
+extern "C"
+{
+#include <satsolver/transaction.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/sat/detail/PoolImpl.h"
+#include "zypp/sat/Transaction.h"
+#include "zypp/sat/Solvable.h"
+#include "zypp/sat/Queue.h"
+#include "zypp/PoolItem.h"
+
+using std::endl;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////
+  namespace sat
+  { /////////////////////////////////////////////////////////////////
+
+    /** Transaction implementation.
+     * \todo check whether the pool serial number changed!
+     */
+    struct Transaction::Impl : protected detail::PoolMember
+    {
+      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;
+
+      public:
+       Impl()
+       { memset( &_trans, 0, sizeof(_trans) ); }
+
+       Impl( ::_Transaction & trans_r )
+         : _watcher(  myPool().serial() )
+       {
+         ::transaction_init_clone( &_trans, &trans_r );
+         // 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 )
+         {
+           sat::Solvable solv( *it );
+           if ( ! solv.isKind<Package>() )
+           {
+             PoolItem pi( solv );
+             if ( pi.buddy() )
+             {
+               _linkMap[*it] = pi.buddy().id();
+             }
+           }
+         }
+       }
+
+       ~Impl()
+       { ::transaction_free( &_trans ); }
+
+      public:
+       bool valid() const
+       { return _watcher.isClean( myPool().serial() ); }
+
+       bool order()
+       {
+         if ( ! valid() )
+           return false;
+#if 0
+         ::transaction_order( &_trans, SOLVER_TRANSACTION_KEEP_ORDERDATA );
+         detail::IdType chosen = 0;
+         Queue choices;
+
+         unsigned stopper = 10;
+         while ( true )
+         {
+//         choices.clear();
+           int ret = transaction_order_add_choices( &_trans, chosen, choices );
+//
+           for_( it, choices.begin(), choices.end() )
+           {
+             if ( chosen )
+             {
+               if ( *it == chosen )
+                 chosen = 0;
+               continue;
+             }
+             if ( makeResObject( sat::Solvable(*it) )->mediaNr() > 1 )
+               continue;
+             chosen = *it;
+             break;
+           }
+           MIL << ret << ": " << chosen << ": " << choices << endl;
+           if ( ! chosen )
+             break;
+           if ( !--stopper )
+             break;
+         }
+
+         return true;
+#endif
+
+         if ( !_ordered )
+         {
+           ::transaction_order( &_trans, 0 );
+           _ordered = true;
+         }
+         return true;
+       }
+
+       bool empty() const
+       { return( _trans.steps.count == 0 ); }
+
+       size_t size() const
+       { return _trans.steps.count; }
+
+       const_iterator begin( const RW_pointer<Transaction::Impl> & self_r ) const
+       { return const_iterator( self_r, _trans.steps.elements ); }
+       iterator begin( const RW_pointer<Transaction::Impl> & self_r )
+       { 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 ); }
+       iterator end( const RW_pointer<Transaction::Impl> & self_r )
+       { 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 ); }
+       iterator find(const RW_pointer<Transaction::Impl> & self_r, const sat::Solvable & solv_r )
+       { detail::IdType * it( _find( solv_r ) ); return it ? iterator( self_r, it ) : end( self_r ); }
+
+      private:
+       detail::IdType * _find( const sat::Solvable & solv_r ) const
+       {
+         if ( solv_r && _trans.steps.elements )
+         {
+           for_( it, _trans.steps.elements, _trans.steps.elements + _trans.steps.count )
+           {
+             if ( *it == detail::IdType(solv_r.id()) )
+               return it;
+           }
+         }
+         return 0;
+       }
+
+      public:
+       StepType stepType( Solvable solv_r ) const
+       {
+         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;
+           case SOLVER_TRANSACTION_MULTIINSTALL: return TRANSACTION_MULTIINSTALL; break;
+         }
+         return TRANSACTION_IGNORE;
+       }
+
+       StepStage stepStage( Solvable solv_r ) const
+       { return stepStage( resolve( solv_r ) ); }
+
+       void stepStage( Solvable solv_r, StepStage newval_r )
+       { stepStage( resolve( solv_r ), newval_r ); }
+
+      private:
+
+       detail::IdType resolve( const Solvable & solv_r ) const
+       {
+         map_type::const_iterator res( _linkMap.find( solv_r.id() ) );
+         return( res == _linkMap.end() ? solv_r.id() : res->second );
+       }
+
+       bool isIn( const set_type & set_r, detail::IdType sid_r ) const
+       { return( set_r.find( sid_r ) != set_r.end() ); }
+
+       StepStage stepStage( detail::IdType sid_r ) const
+       {
+         if ( isIn( _doneSet, sid_r ) )
+           return STEP_DONE;
+         if ( isIn( _errSet, sid_r ) )
+           return STEP_ERROR;
+         return STEP_TODO;
+       }
+
+       void stepStage( detail::IdType sid_r, StepStage newval_r )
+       {
+         StepStage stage( stepStage( sid_r ) );
+         if ( stage != newval_r )
+         {
+           // reset old stage
+           if ( stage != STEP_TODO )
+           {
+             (stage == STEP_DONE ? _doneSet : _errSet).erase( sid_r );
+           }
+           if ( newval_r != STEP_TODO )
+           {
+             (newval_r == STEP_DONE ? _doneSet : _errSet).insert( sid_r );
+           }
+         }
+       }
+     private:
+       SerialNumberWatcher _watcher;
+       mutable ::Transaction _trans;
+       DefaultIntegral<bool,false> _ordered;
+       //
+       set_type _doneSet;
+       set_type _errSet;
+       map_type _linkMap;
+
+      public:
+        /** Offer default Impl. */
+        static shared_ptr<Impl> nullimpl()
+        {
+          static shared_ptr<Impl> _nullimpl( new Impl );
+          return _nullimpl;
+        }
+    };
+
+    /** \relates Transaction::Impl Stream output */
+    inline std::ostream & operator<<( std::ostream & str, const Transaction::Impl & obj )
+    {
+      return str << "Transaction: " << obj.size() << " (" << (obj.valid()?"valid":"INVALID") << ")";
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : Transaction
+    //
+    ///////////////////////////////////////////////////////////////////
+
+    Transaction::Transaction()
+      : _pimpl( Impl::nullimpl() )
+    {}
+
+    Transaction::Transaction( ::_Transaction & trans_r )
+      : _pimpl( new Impl( trans_r ) )
+    {}
+
+    Transaction::~Transaction()
+    {}
+
+    bool Transaction::valid() const
+    { return _pimpl->valid(); }
+
+    bool Transaction::order()
+    { return _pimpl->order(); }
+
+    bool Transaction::empty() const
+    { return _pimpl->empty(); }
+
+    size_t Transaction::size() const
+    { return _pimpl->size(); }
+
+    Transaction::const_iterator Transaction::begin() const
+    { return _pimpl->begin( _pimpl ); }
+
+    Transaction::iterator Transaction::begin()
+    { return _pimpl->begin( _pimpl ); }
+
+    Transaction::const_iterator Transaction::end() const
+    { return _pimpl->end( _pimpl ); }
+
+    Transaction::iterator Transaction::end()
+    { return _pimpl->end( _pimpl ); }
+
+    Transaction::const_iterator Transaction::find( const sat::Solvable & solv_r ) const
+    { return _pimpl->find( _pimpl, solv_r ); }
+
+    Transaction::iterator Transaction::find( const sat::Solvable & solv_r )
+    { return _pimpl->find( _pimpl, solv_r ); }
+
+    std::ostream & operator<<( std::ostream & str, const Transaction & obj )
+    { return str << *obj._pimpl; }
+
+    std::ostream & dumpOn( std::ostream & str, const Transaction & obj )
+    {
+      for_( it, obj.begin(), obj.end() )
+      {
+       str << *it << endl;
+      }
+      return str;
+    }
+
+    bool operator==( const Transaction & lhs, const Transaction & rhs )
+    { return lhs._pimpl == rhs._pimpl; }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : Transaction::Step
+    //
+    ///////////////////////////////////////////////////////////////////
+
+    Transaction::Step::Step()
+    {}
+
+    Transaction::StepType Transaction::Step::stepType() const
+    { return _pimpl->stepType( _solv ); }
+
+    Transaction::StepStage Transaction::Step::stepStage() const
+    { return _pimpl->stepStage( _solv ); }
+
+    void Transaction::Step::stepStage( StepStage val_r )
+    { _pimpl->stepStage( _solv, val_r ); }
+
+    std::ostream & operator<<( std::ostream & str, const Transaction::Step & obj )
+    { return str << obj.stepType() << obj.stepStage() << " " << PoolItem( obj.satSolvable() ); }
+
+    std::ostream & operator<<( std::ostream & str, Transaction::StepType obj )
+    {
+      switch ( obj )
+      {
+       #define OUTS(E,S) case Transaction::E: return str << #S; break
+       OUTS( TRANSACTION_IGNORE,       [ ] );
+       OUTS( TRANSACTION_ERASE,        [-] );
+       OUTS( TRANSACTION_INSTALL,      [+] );
+       OUTS( TRANSACTION_MULTIINSTALL, [M] );
+       #undef OUTS
+      }
+    }
+
+    std::ostream & operator<<( std::ostream & str, Transaction::StepStage obj )
+    {
+      switch ( obj )
+      {
+       #define OUTS(E,S) case Transaction::E: return str << #S; break
+       OUTS( STEP_TODO,        [__] );
+       OUTS( STEP_DONE,        [OK] );
+       OUTS( STEP_ERROR,       [**] );
+       #undef OUTS
+      }
+    }
+    ///////////////////////////////////////////////////////////////////
+    namespace detail
+    { /////////////////////////////////////////////////////////////////
+      ///////////////////////////////////////////////////////////////////
+      //
+      //       CLASS NAME : Transaction::const_iterator/iterator
+      //
+      ///////////////////////////////////////////////////////////////////
+
+      Transaction_const_iterator::Transaction_const_iterator()
+      : Transaction_const_iterator::iterator_adaptor_( 0 )
+      {}
+
+      Transaction_const_iterator::Transaction_const_iterator( const Transaction_iterator & iter_r )
+      : Transaction_const_iterator::iterator_adaptor_( iter_r.base() )
+      , _pimpl( iter_r._pimpl )
+      {}
+
+      Transaction_iterator::Transaction_iterator()
+      : Transaction_iterator::iterator_adaptor_( 0 )
+      {}
+
+      /////////////////////////////////////////////////////////////////
+    } // namespace detail
+    ///////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////
+  } // namespace sat
+  ///////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/sat/Transaction.h b/zypp/sat/Transaction.h
new file mode 100644 (file)
index 0000000..e622023
--- /dev/null
@@ -0,0 +1,315 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp/sat/Transaction.h
+ */
+extern "C"
+{
+  struct _Transaction;
+}
+#ifndef ZYPP_SAT_TRANSACTION_H
+#define ZYPP_SAT_TRANSACTION_H
+
+#include <iosfwd>
+
+#include "zypp/base/PtrTypes.h"
+#include "zypp/base/SafeBool.h"
+#include "zypp/base/Iterator.h"
+#include "zypp/base/DefaultIntegral.h"
+
+#include "zypp/sat/detail/PoolImpl.h"
+#include "zypp/sat/SolvIterMixin.h"
+#include "zypp/sat/Solvable.h"
+
+#include "zypp/PoolItem.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////
+  namespace sat
+  { /////////////////////////////////////////////////////////////////
+
+    namespace detail
+    {
+      /** Needs to be outside \ref Transaction in order to be usable in SolvIterMixin. */
+      class Transaction_iterator;
+      /** Needs to be outside \ref Transaction in order to be usable in SolvIterMixin. */
+      class Transaction_const_iterator;
+    }
+
+    /** Satsolver transaction wrapper.
+     * \note Note that Transaction is derived from \ref sat::SolvIterMixin which
+     *       makes PoolItem and Selectable iterators automatically available.
+     * \note Changing the \ref ResPool content (loading/unloading repositories)
+     *       invalidates all outstanding transaction data. \see \ref valid.
+     */
+    class Transaction : public SolvIterMixin<Transaction, detail::Transaction_const_iterator>
+                     , protected base::SafeBool<Transaction>
+    {
+      friend std::ostream & operator<<( std::ostream & str, const Transaction & obj );
+      friend std::ostream & dumpOn( std::ostream & str, const Transaction & obj );
+      friend bool operator==( const Transaction & lhs, const Transaction & rhs );
+
+     public:
+       /** Represents a single step within a \ref Transaction. */
+       class Step;
+
+       /** Type of (rpm) action to perform in a \ref Step. */
+       enum StepType
+       {
+        TRANSACTION_IGNORE,            /**< [ ] Nothing (includes implicit deletes due to obsoletes and non-package actions) */
+        TRANSACTION_ERASE,             /**< [-] Delete item */
+        TRANSACTION_INSTALL,           /**< [+] Install(update) item */
+        TRANSACTION_MULTIINSTALL       /**< [M] Install(multiversion) item (\see \ref ZConfig::multiversion) */
+       };
+
+       /** \ref Step action result. */
+       enum StepStage
+       {
+        STEP_TODO,             /**< [__] unprocessed */
+        STEP_DONE,             /**< [OK] success */
+        STEP_ERROR,            /**< [**] error */
+       };
+
+     public:
+        /** Default ctor: empty transaction. */
+        Transaction();
+
+        /** Ctor cloning a sat transaction. */
+        Transaction( ::_Transaction & trans_r );
+
+        /** Dtor */
+        ~Transaction();
+
+      public:
+       /** Whether transaction actually contains data and also fits the current pools content. */
+       bool valid() const;
+
+        /**  Validate object in a boolean context: valid */
+        using base::SafeBool<Transaction>::operator bool_type;
+
+       /** Order transaction steps for commit.
+        * It's cheap to call it for an aleready ordered \ref Transaction.
+        * This invalidates outstanding iterators. Returns whether
+        * \ref Transaction is \ref valid.
+        */
+       bool order();
+
+       /** Whether the transaction contains any steps. */
+       bool empty() const;
+
+       /** Number of steps in transaction steps. */
+       size_t size() const;
+
+       typedef detail::Transaction_iterator iterator;
+       typedef detail::Transaction_const_iterator const_iterator;
+
+       /** Iterator to the first \ref TransactionStep */
+       const_iterator begin() const;
+       /** \overload */
+       iterator begin();
+
+       /** Iterator behind the last \ref TransactionStep */
+       const_iterator end() const;
+       /** \overload */
+       iterator end();
+
+       /** Return iterator pointing to \a solv_r or \ref end. */
+       const_iterator find( const sat::Solvable & solv_r ) const;
+       iterator find( const sat::Solvable & solv_r );
+       /** \overload */
+       const_iterator find( const ResObject::constPtr & resolvable_r ) const;
+       iterator find( const ResObject::constPtr & resolvable_r );
+       /** \overload */
+       const_iterator find( const PoolItem & pi_r ) const;
+       iterator find( const PoolItem & pi_r );
+
+      public:
+       /** \name Omit iterating TRANSACTION_IGNORE steps.
+        */
+       //@{
+       struct FilterAction;
+       typedef filter_iterator<FilterAction,const_iterator> action_iterator;
+       action_iterator actionBegin() const;
+       action_iterator actionEnd() const;
+       //@}
+
+      private:
+        friend base::SafeBool<Transaction>::operator bool_type() const;
+        /**  Validate object in a boolean context. */
+        bool boolTest() const
+        { return valid(); }
+      public:
+        /** Implementation  */
+        class Impl;
+      private:
+        /** Pointer to implementation */
+        RW_pointer<Impl> _pimpl;
+    };
+
+    /** \relates Transaction Stream output */
+    std::ostream & operator<<( std::ostream & str, const Transaction & obj );
+
+    /** \relates Transaction Verbose stream output */
+    std::ostream & dumpOn( std::ostream & str, const Transaction & obj );
+
+    /** \relates Transaction */
+    bool operator==( const Transaction & lhs, const Transaction & rhs );
+
+    /** \relates Transaction */
+    inline bool operator!=( const Transaction & lhs, const Transaction & rhs )
+    { return !( lhs == rhs ); }
+
+
+    /** A single step within a \ref Transaction.
+     * \see \ref Transaction.
+     */
+    class Transaction::Step
+    {
+      friend std::ostream & operator<<( std::ostream & str, const Step & obj );
+
+      public:
+       Step();
+       Step( const RW_pointer<Impl> & pimpl_r, detail::IdType id_r )
+         : _solv( id_r )
+         , _pimpl( pimpl_r )
+       {}
+
+      public:
+       /** Type of action to perform in this step. */
+       StepType stepType() const;
+
+       /** Step action result. */
+       StepStage stepStage() const;
+
+       /** Set step action result. */
+       void stepStage( StepStage val_r );
+
+       /** Return the corresponding \ref Solvable. */
+       Solvable satSolvable() const
+       { return _solv; }
+
+       /** Implicit conversion to \ref Solvable */
+       operator const Solvable &() const { return _solv; }
+       /** \overload nonconst */
+       operator Solvable &() { return _solv; }
+
+      private:
+       Solvable _solv;
+       /** Pointer to implementation */
+       RW_pointer<Impl> _pimpl;
+    };
+
+    /** \relates Transaction::Step Stream output */
+    std::ostream & operator<<( std::ostream & str, const Transaction::Step & obj );
+
+    /** \relates Transaction::StepType Stream output */
+    std::ostream & operator<<( std::ostream & str, Transaction::StepType obj );
+
+    /** \relates Transaction::StepStage Stream output */
+    std::ostream & operator<<( std::ostream & str, Transaction::StepStage obj );
+
+   ///////////////////////////////////////////////////////////////////
+    namespace detail
+    { /////////////////////////////////////////////////////////////////
+
+      /** \ref Transaction iterator.
+       */
+      class Transaction_iterator : public boost::iterator_adaptor<
+      Transaction_iterator             // Derived
+      , const detail::IdType *         // Base
+      , Transaction::Step              // Value
+      , boost::forward_traversal_tag   // CategoryOrTraversal
+      , Transaction::Step              // Reference
+      >
+      {
+       public:
+         Transaction_iterator();
+         Transaction_iterator( const RW_pointer<Transaction::Impl> & pimpl_r, base_type id_r )
+         : Transaction_iterator::iterator_adaptor_( id_r )
+         , _pimpl( pimpl_r )
+         {}
+
+       private:
+         friend class boost::iterator_core_access;
+
+         reference dereference() const
+         { return Transaction::Step( _pimpl, *base() ); }
+
+       private:
+         friend class Transaction_const_iterator;
+         /** Pointer to implementation */
+         RW_pointer<Transaction::Impl> _pimpl;
+      };
+
+     /** \ref Transaction const_iterator.
+       */
+      class Transaction_const_iterator : public boost::iterator_adaptor<
+      Transaction_const_iterator       // Derived
+      , const detail::IdType *         // Base
+      , const Transaction::Step                // Value
+      , boost::forward_traversal_tag   // CategoryOrTraversal
+      , const Transaction::Step                // Reference
+      >
+      {
+       public:
+         Transaction_const_iterator();
+         Transaction_const_iterator( const Transaction_iterator & iter_r );
+         Transaction_const_iterator( const RW_pointer<Transaction::Impl> & pimpl_r, base_type id_r )
+         : Transaction_const_iterator::iterator_adaptor_( id_r )
+         , _pimpl( pimpl_r )
+         {}
+
+       private:
+         friend class boost::iterator_core_access;
+
+         reference dereference() const
+         { return Transaction::Step( _pimpl, *base() ); }
+
+       private:
+         /** Pointer to implementation */
+         RW_pointer<Transaction::Impl> _pimpl;
+      };
+
+       /////////////////////////////////////////////////////////////////
+    } // namespace detail
+    ///////////////////////////////////////////////////////////////////
+
+    inline Transaction::const_iterator Transaction::find( const ResObject::constPtr & resolvable_r ) const
+    { return( resolvable_r ? find( resolvable_r->satSolvable() ) : end() ); }
+
+    inline Transaction::iterator Transaction::find( const ResObject::constPtr & resolvable_r )
+    { return( resolvable_r ? find( resolvable_r->satSolvable() ) : end() ); }
+
+    inline Transaction::const_iterator Transaction::find( const PoolItem & pi_r ) const
+    { return find( pi_r.satSolvable() ); }
+
+    inline Transaction::iterator Transaction::find( const PoolItem & pi_r )
+    { return find( pi_r.satSolvable() ); }
+
+
+    struct  Transaction::FilterAction
+    {
+      bool operator()( const Transaction::Step & step_r ) const
+      { return step_r.stepType() != Transaction::TRANSACTION_IGNORE; }
+    };
+
+    inline Transaction::action_iterator Transaction::actionBegin() const
+    { return make_filter_begin( FilterAction(), *this ); }
+
+    inline Transaction::action_iterator Transaction::actionEnd() const
+    { return make_filter_end( FilterAction(), *this ); }
+
+     /////////////////////////////////////////////////////////////////
+  } // namespace sat
+  ///////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_SAT_TRANSACTION_H
index e4d81e6..11b5993 100644 (file)
@@ -35,6 +35,7 @@
 #include "zypp/ResFilters.h"
 #include "zypp/sat/Pool.h"
 #include "zypp/sat/Solvable.h"
+#include "zypp/sat/Transaction.h"
 
 #define MAXSOLVERRUNS 5
 
@@ -355,6 +356,8 @@ bool Resolver::resolveQueue( solver::detail::SolverQueueItemList & queue )
     return _satResolver->resolveQueue(queue, _addWeak);
 }
 
+sat::Transaction Resolver::getTransaction()
+{ return _satResolver->getTransaction(); }
 
 //----------------------------------------------------------------------------
 // Getting more information about the solve results
index 77a0969..0db4c2a 100644 (file)
 /////////////////////////////////////////////////////////////////////////
 namespace zypp
 { ///////////////////////////////////////////////////////////////////////
+
+  namespace sat
+  {
+    class Transaction;
+  }
+
   ///////////////////////////////////////////////////////////////////////
   namespace solver
   { /////////////////////////////////////////////////////////////////////
@@ -213,6 +219,9 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable {
     ResolverProblemList problems() const;
     void applySolutions( const ProblemSolutionList & solutions );
 
+    // Return the Transaction computed by the last solver run.
+    sat::Transaction getTransaction();
+
     // reset all SOLVER transaction in pool
     void undo();
 
index ec5dbfa..a2629bb 100644 (file)
@@ -51,6 +51,7 @@ extern "C"
 #include "zypp/solver/detail/SolverQueueItemInstall.h"
 #include "zypp/solver/detail/SolverQueueItemDelete.h"
 #include "zypp/solver/detail/SystemCheck.h"
+#include "zypp/sat/Transaction.h"
 
 /////////////////////////////////////////////////////////////////////////
 namespace zypp
@@ -161,6 +162,12 @@ SATResolver::~SATResolver()
 
 //---------------------------------------------------------------------------
 
+sat::Transaction SATResolver::getTransaction()
+{
+  if ( !_solv )
+    return sat::Transaction();
+  return sat::Transaction( _solv->trans );
+}
 
 ResPool
 SATResolver::pool (void) const
@@ -168,7 +175,6 @@ SATResolver::pool (void) const
     return _pool;
 }
 
-
 void
 SATResolver::resetItemTransaction (PoolItem item)
 {
index 56140d0..31b5054 100644 (file)
@@ -43,10 +43,15 @@ extern "C"
 #include "zypp/Capability.h"
 #include "zypp/solver/detail/SolverQueueItem.h"
 
-
 /////////////////////////////////////////////////////////////////////////
 namespace zypp
 { ///////////////////////////////////////////////////////////////////////
+
+  namespace sat
+  {
+    class Transaction;
+  }
+
   ///////////////////////////////////////////////////////////////////////
   namespace solver
   { /////////////////////////////////////////////////////////////////////
@@ -154,6 +159,9 @@ class SATResolver : public base::ReferenceCounted, private base::NonCopyable {
     ResolverProblemList problems ();
     void applySolutions (const ProblemSolutionList &solutions);
 
+    // Return the Transaction computed by the last solver run.
+    sat::Transaction getTransaction();
+
     void addPoolItemToInstall (PoolItem item);
     void addPoolItemsToInstallFromList (PoolItemList & rl);