Do commit based on sat::Transaction.
[platform/upstream/libzypp.git] / zypp / sat / Transaction.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/sat/Transaction.h
10  */
11 extern "C"
12 {
13   struct _Transaction;
14 }
15 #ifndef ZYPP_SAT_TRANSACTION_H
16 #define ZYPP_SAT_TRANSACTION_H
17
18 #include <iosfwd>
19
20 #include "zypp/base/PtrTypes.h"
21 #include "zypp/base/SafeBool.h"
22 #include "zypp/base/Iterator.h"
23 #include "zypp/base/DefaultIntegral.h"
24
25 #include "zypp/sat/detail/PoolImpl.h"
26 #include "zypp/sat/SolvIterMixin.h"
27 #include "zypp/sat/Solvable.h"
28
29 #include "zypp/PoolItem.h"
30
31 ///////////////////////////////////////////////////////////////////
32 namespace zypp
33 { /////////////////////////////////////////////////////////////////
34   ///////////////////////////////////////////////////////////////////
35   namespace sat
36   { /////////////////////////////////////////////////////////////////
37
38     namespace detail
39     {
40       /** Needs to be outside \ref Transaction in order to be usable in SolvIterMixin. */
41       class Transaction_iterator;
42       /** Needs to be outside \ref Transaction in order to be usable in SolvIterMixin. */
43       class Transaction_const_iterator;
44     }
45
46     /** Satsolver transaction wrapper.
47      * \note Note that Transaction is derived from \ref sat::SolvIterMixin which
48      *       makes PoolItem and Selectable iterators automatically available.
49      * \note Changing the \ref ResPool content (loading/unloading repositories)
50      *       invalidates all outstanding transaction data. \see \ref valid.
51      */
52     class Transaction : public SolvIterMixin<Transaction, detail::Transaction_const_iterator>
53                       , protected base::SafeBool<Transaction>
54     {
55       friend std::ostream & operator<<( std::ostream & str, const Transaction & obj );
56       friend std::ostream & dumpOn( std::ostream & str, const Transaction & obj );
57       friend bool operator==( const Transaction & lhs, const Transaction & rhs );
58
59      public:
60        /** Represents a single step within a \ref Transaction. */
61        class Step;
62
63        /** Type of (rpm) action to perform in a \ref Step. */
64        enum StepType
65        {
66          TRANSACTION_IGNORE,            /**< [ ] Nothing (includes implicit deletes due to obsoletes and non-package actions) */
67          TRANSACTION_ERASE,             /**< [-] Delete item */
68          TRANSACTION_INSTALL,           /**< [+] Install(update) item */
69          TRANSACTION_MULTIINSTALL       /**< [M] Install(multiversion) item (\see \ref ZConfig::multiversion) */
70        };
71
72        /** \ref Step action result. */
73        enum StepStage
74        {
75          STEP_TODO,             /**< [__] unprocessed */
76          STEP_DONE,             /**< [OK] success */
77          STEP_ERROR,            /**< [**] error */
78        };
79
80      public:
81         /** Default ctor: empty transaction. */
82         Transaction();
83
84         /** Ctor cloning a sat transaction. */
85         Transaction( ::_Transaction & trans_r );
86
87         /** Dtor */
88         ~Transaction();
89
90       public:
91         /** Whether transaction actually contains data and also fits the current pools content. */
92         bool valid() const;
93
94         /**  Validate object in a boolean context: valid */
95         using base::SafeBool<Transaction>::operator bool_type;
96
97         /** Order transaction steps for commit.
98          * It's cheap to call it for an aleready ordered \ref Transaction.
99          * This invalidates outstanding iterators. Returns whether
100          * \ref Transaction is \ref valid.
101          */
102         bool order();
103
104         /** Whether the transaction contains any steps. */
105         bool empty() const;
106
107         /** Number of steps in transaction steps. */
108         size_t size() const;
109
110        typedef detail::Transaction_iterator iterator;
111        typedef detail::Transaction_const_iterator const_iterator;
112
113         /** Iterator to the first \ref TransactionStep */
114         const_iterator begin() const;
115         /** \overload */
116         iterator begin();
117
118         /** Iterator behind the last \ref TransactionStep */
119         const_iterator end() const;
120         /** \overload */
121         iterator end();
122
123         /** Return iterator pointing to \a solv_r or \ref end. */
124         const_iterator find( const sat::Solvable & solv_r ) const;
125         iterator find( const sat::Solvable & solv_r );
126         /** \overload */
127         const_iterator find( const ResObject::constPtr & resolvable_r ) const;
128         iterator find( const ResObject::constPtr & resolvable_r );
129         /** \overload */
130         const_iterator find( const PoolItem & pi_r ) const;
131         iterator find( const PoolItem & pi_r );
132
133       public:
134         /** \name Omit iterating TRANSACTION_IGNORE steps.
135          */
136         //@{
137         struct FilterAction;
138         typedef filter_iterator<FilterAction,const_iterator> action_iterator;
139         action_iterator actionBegin() const;
140         action_iterator actionEnd() const;
141         //@}
142
143       private:
144         friend base::SafeBool<Transaction>::operator bool_type() const;
145         /**  Validate object in a boolean context. */
146         bool boolTest() const
147         { return valid(); }
148       public:
149         /** Implementation  */
150         class Impl;
151       private:
152         /** Pointer to implementation */
153         RW_pointer<Impl> _pimpl;
154     };
155
156     /** \relates Transaction Stream output */
157     std::ostream & operator<<( std::ostream & str, const Transaction & obj );
158
159     /** \relates Transaction Verbose stream output */
160     std::ostream & dumpOn( std::ostream & str, const Transaction & obj );
161
162     /** \relates Transaction */
163     bool operator==( const Transaction & lhs, const Transaction & rhs );
164
165     /** \relates Transaction */
166     inline bool operator!=( const Transaction & lhs, const Transaction & rhs )
167     { return !( lhs == rhs ); }
168
169
170     /** A single step within a \ref Transaction.
171      *
172      * \note After commit, when the @System repo (rpm database) is reread, all
173      * @System solvables within the transaction are invalidated (they got deleted).
174      * Thats why we internally store the NVRA, so you can access \ref ident
175      * (\see \ref sat::Solvable::ident), \ref edition, \ref arch of a deleted package,
176      * even if the \ref satSolvable itself is meanwhile invalid.
177      *
178      * \see \ref Transaction.
179      */
180     class Transaction::Step
181     {
182       friend std::ostream & operator<<( std::ostream & str, const Step & obj );
183
184       public:
185         Step();
186         Step( const RW_pointer<Impl> & pimpl_r, detail::IdType id_r )
187           : _solv( id_r )
188           , _pimpl( pimpl_r )
189         {}
190
191       public:
192         /** Type of action to perform in this step. */
193         StepType stepType() const;
194
195         /** Step action result. */
196         StepStage stepStage() const;
197
198         /** Set step action result. */
199         void stepStage( StepStage val_r );
200
201         /** Return the corresponding \ref Solvable (or.
202          *
203          */
204         Solvable satSolvable() const
205         { return _solv; }
206
207         /** \name Post mortem acccess to @System solvables
208          * \code
209          *   Transaction::Step step;
210          *   if ( step.satSolvable() )
211          *     std::cout << step.satSolvable() << endl;
212          *   else
213          *     std::cout << step.ident() << endl; // deleted @System solvable
214          * \endcode
215          */
216         //@{
217         /** \see \ref sat::Solvable::ident. */
218         IdString ident() const;
219
220         /** \see \ref sat::Solvable::edition. */
221         Edition edition() const;
222
223         /** \see \ref sat::Solvable::arch. */
224         Arch arch() const;
225         //@}
226
227         /** Implicit conversion to \ref Solvable */
228         operator const Solvable &() const { return _solv; }
229         /** \overload nonconst */
230         operator Solvable &() { return _solv; }
231
232       private:
233         Solvable _solv;
234         /** Pointer to implementation */
235         RW_pointer<Impl> _pimpl;
236     };
237
238     /** \relates Transaction::Step Stream output */
239     std::ostream & operator<<( std::ostream & str, const Transaction::Step & obj );
240
241     /** \relates Transaction::StepType Stream output */
242     std::ostream & operator<<( std::ostream & str, Transaction::StepType obj );
243
244     /** \relates Transaction::StepStage Stream output */
245     std::ostream & operator<<( std::ostream & str, Transaction::StepStage obj );
246
247    ///////////////////////////////////////////////////////////////////
248     namespace detail
249     { /////////////////////////////////////////////////////////////////
250
251       /** \ref Transaction iterator.
252        */
253       class Transaction_iterator : public boost::iterator_adaptor<
254       Transaction_iterator              // Derived
255       , const detail::IdType *          // Base
256       , Transaction::Step               // Value
257       , boost::forward_traversal_tag    // CategoryOrTraversal
258       , Transaction::Step               // Reference
259       >
260       {
261         public:
262           Transaction_iterator();
263           Transaction_iterator( const RW_pointer<Transaction::Impl> & pimpl_r, base_type id_r )
264           : Transaction_iterator::iterator_adaptor_( id_r )
265           , _pimpl( pimpl_r )
266           {}
267
268         private:
269           friend class boost::iterator_core_access;
270
271           reference dereference() const
272           { return Transaction::Step( _pimpl, *base() ); }
273
274         private:
275           friend class Transaction_const_iterator;
276           /** Pointer to implementation */
277           RW_pointer<Transaction::Impl> _pimpl;
278       };
279
280      /** \ref Transaction const_iterator.
281        */
282       class Transaction_const_iterator : public boost::iterator_adaptor<
283       Transaction_const_iterator        // Derived
284       , const detail::IdType *          // Base
285       , const Transaction::Step         // Value
286       , boost::forward_traversal_tag    // CategoryOrTraversal
287       , const Transaction::Step         // Reference
288       >
289       {
290         public:
291           Transaction_const_iterator();
292           Transaction_const_iterator( const Transaction_iterator & iter_r );
293           Transaction_const_iterator( const RW_pointer<Transaction::Impl> & pimpl_r, base_type id_r )
294           : Transaction_const_iterator::iterator_adaptor_( id_r )
295           , _pimpl( pimpl_r )
296           {}
297
298         private:
299           friend class boost::iterator_core_access;
300
301           reference dereference() const
302           { return Transaction::Step( _pimpl, *base() ); }
303
304         private:
305           /** Pointer to implementation */
306           RW_pointer<Transaction::Impl> _pimpl;
307       };
308
309        /////////////////////////////////////////////////////////////////
310     } // namespace detail
311     ///////////////////////////////////////////////////////////////////
312
313     inline Transaction::const_iterator Transaction::find( const ResObject::constPtr & resolvable_r ) const
314     { return( resolvable_r ? find( resolvable_r->satSolvable() ) : end() ); }
315
316     inline Transaction::iterator Transaction::find( const ResObject::constPtr & resolvable_r )
317     { return( resolvable_r ? find( resolvable_r->satSolvable() ) : end() ); }
318
319     inline Transaction::const_iterator Transaction::find( const PoolItem & pi_r ) const
320     { return find( pi_r.satSolvable() ); }
321
322     inline Transaction::iterator Transaction::find( const PoolItem & pi_r )
323     { return find( pi_r.satSolvable() ); }
324
325
326     struct  Transaction::FilterAction
327     {
328       bool operator()( const Transaction::Step & step_r ) const
329       { return step_r.stepType() != Transaction::TRANSACTION_IGNORE; }
330     };
331
332     inline Transaction::action_iterator Transaction::actionBegin() const
333     { return make_filter_begin( FilterAction(), *this ); }
334
335     inline Transaction::action_iterator Transaction::actionEnd() const
336     { return make_filter_end( FilterAction(), *this ); }
337
338      /////////////////////////////////////////////////////////////////
339   } // namespace sat
340   ///////////////////////////////////////////////////////////////////
341   /////////////////////////////////////////////////////////////////
342 } // namespace zypp
343 ///////////////////////////////////////////////////////////////////
344 #endif // ZYPP_SAT_TRANSACTION_H