- remove old sat transaction argument in Transaction constructor. Cleanup code.
[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/Flags.h"
22 #include "zypp/base/SafeBool.h"
23 #include "zypp/base/Iterator.h"
24 #include "zypp/base/DefaultIntegral.h"
25
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     /** Libsolv 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      * \note.The transaction may inlude steps of type \ref TRANSACTION_IGNORE which
52      *       do not cause/require any specific action. To skip those informal steps
53      *       when iterating, use the \ref actionBegin /\ref actionEnd methods.
54      */
55     class Transaction : public SolvIterMixin<Transaction, detail::Transaction_const_iterator>
56                       , protected base::SafeBool<Transaction>
57     {
58       friend std::ostream & operator<<( std::ostream & str, const Transaction & obj );
59       friend std::ostream & dumpOn( std::ostream & str, const Transaction & obj );
60       friend bool operator==( const Transaction & lhs, const Transaction & rhs );
61
62      public:
63        /** Represents a single step within a \ref Transaction. */
64        class Step;
65
66        /** Type of (rpm) action to perform in a \ref Step. */
67        enum StepType
68        {
69          TRANSACTION_IGNORE             = 0x00, /**< [ ] Nothing (includes implicit deletes due to obsoletes and non-package actions) */
70          TRANSACTION_ERASE              = 0x10, /**< [-] Delete item */
71          TRANSACTION_INSTALL            = 0x20, /**< [+] Install(update) item */
72          TRANSACTION_MULTIINSTALL       = 0x30  /**< [M] Install(multiversion) item (\see \ref ZConfig::multiversion) */
73        };
74
75        /** \ref Step action result. */
76        enum StepStage
77        {
78          STEP_TODO      = (1 << 0),     /**< [__] unprocessed */
79          STEP_DONE      = (1 << 1),     /**< [OK] success */
80          STEP_ERROR     = (1 << 2),     /**< [**] error */
81        };
82
83        ZYPP_DECLARE_FLAGS(StepStages,StepStage);
84
85      public:
86         /** Ctor: create transaction from ResPool. */
87         Transaction();
88
89         /** Dtor */
90         ~Transaction();
91
92       public:
93         /** Whether transaction actually contains data and also fits the current pools content. */
94         bool valid() const;
95
96         /**  Validate object in a boolean context: valid */
97         using base::SafeBool<Transaction>::operator bool_type;
98
99         /** Order transaction steps for commit.
100          * It's cheap to call it for an aleready ordered \ref Transaction.
101          * This invalidates outstanding iterators. Returns whether
102          * \ref Transaction is \ref valid.
103          */
104         bool order();
105
106         /** Whether the transaction contains any steps. */
107         bool empty() const;
108
109         /** Number of steps in transaction steps. */
110         size_t size() const;
111
112         typedef detail::Transaction_iterator iterator;
113         typedef detail::Transaction_const_iterator const_iterator;
114
115         /** Iterator to the first \ref TransactionStep */
116         const_iterator begin() const;
117         /** \overload */
118         iterator begin();
119
120         /** Iterator behind the last \ref TransactionStep */
121         const_iterator end() const;
122         /** \overload */
123         iterator end();
124
125         /** Return iterator pointing to \a solv_r or \ref end. */
126         const_iterator find( const sat::Solvable & solv_r ) const;
127         iterator find( const sat::Solvable & solv_r );
128         /** \overload */
129         const_iterator find( const ResObject::constPtr & resolvable_r ) const;
130         iterator find( const ResObject::constPtr & resolvable_r );
131         /** \overload */
132         const_iterator find( const PoolItem & pi_r ) const;
133         iterator find( const PoolItem & pi_r );
134
135       public:
136         /** \name Iterate action steps (omit TRANSACTION_IGNORE steps).
137          *
138          * All these methods allow to pass an optional OR'd combination of
139          * \ref StepStages as filter. Per default all steps are processed/counted.
140          *
141          * \code
142          *    Transaction trans;
143          *    for_( it, trans.actionBegin(~sat::Transaction::STEP_DONE), trans.actionEnd() )
144          *    {
145          *       ... // process all steps not DONE (ERROR and TODO)
146          *    }
147          * \endcode
148          */
149         //@{
150         struct FilterAction;
151         typedef filter_iterator<FilterAction,const_iterator> action_iterator;
152
153         /** Whether the [filtered] transaction contains any steps . */
154         bool actionEmpty( StepStages filter_r = StepStages() ) const;
155
156         /** Number of steps in [filtered] transaction steps. */
157         size_t actionSize( StepStages filter_r = StepStages() ) const;
158
159         /** Pointer to the 1st action step in [filtered] transaction. */
160         action_iterator actionBegin( StepStages filter_r = StepStages() ) const;
161
162         /** Pointer behind the last action step in transaction. */
163         action_iterator actionEnd() const;
164
165         //@}
166
167       private:
168         friend base::SafeBool<Transaction>::operator bool_type() const;
169         /**  Validate object in a boolean context. */
170         bool boolTest() const
171         { return valid(); }
172       public:
173         /** Implementation  */
174         class Impl;
175       private:
176         /** Pointer to implementation */
177         RW_pointer<Impl> _pimpl;
178     };
179
180     ZYPP_DECLARE_OPERATORS_FOR_FLAGS(Transaction::StepStages);
181
182     /** \relates Transaction Stream output */
183     std::ostream & operator<<( std::ostream & str, const Transaction & obj );
184
185     /** \relates Transaction Verbose stream output */
186     std::ostream & dumpOn( std::ostream & str, const Transaction & obj );
187
188     /** \relates Transaction */
189     bool operator==( const Transaction & lhs, const Transaction & rhs );
190
191     /** \relates Transaction */
192     inline bool operator!=( const Transaction & lhs, const Transaction & rhs )
193     { return !( lhs == rhs ); }
194
195
196     /** A single step within a \ref Transaction.
197      *
198      * \note After commit, when the @System repo (rpm database) is reread, all
199      * @System solvables within the transaction are invalidated (they got deleted).
200      * Thats why we internally store the NVRA, so you can access \ref ident
201      * (\see \ref sat::Solvable::ident), \ref edition, \ref arch of a deleted package,
202      * even if the \ref satSolvable itself is meanwhile invalid.
203      *
204      * \see \ref Transaction.
205      */
206     class Transaction::Step
207     {
208       friend std::ostream & operator<<( std::ostream & str, const Step & obj );
209
210       public:
211         Step();
212         Step( const RW_pointer<Impl> & pimpl_r, detail::IdType id_r )
213           : _solv( id_r )
214           , _pimpl( pimpl_r )
215         {}
216
217       public:
218         /** Type of action to perform in this step. */
219         StepType stepType() const;
220
221         /** Step action result. */
222         StepStage stepStage() const;
223
224         /** Set step action result. */
225         void stepStage( StepStage val_r );
226
227         /** Return the corresponding \ref Solvable.
228          * Returns \ref Solvable::noSolvable if the item is meanwhile deleted and
229          * was removed from the pool. \see Post mortem acccess to @System solvables.
230          */
231         Solvable satSolvable() const
232         { return _solv; }
233
234         /** \name Post mortem acccess to @System solvables
235          * \code
236          *   Transaction::Step step;
237          *   if ( step.satSolvable() )
238          *     std::cout << step.satSolvable() << endl;
239          *   else
240          *     std::cout << step.ident() << endl; // deleted @System solvable
241          * \endcode
242          */
243         //@{
244         /** \see \ref sat::Solvable::ident. */
245         IdString ident() const;
246
247         /** \see \ref sat::Solvable::edition. */
248         Edition edition() const;
249
250         /** \see \ref sat::Solvable::arch. */
251         Arch arch() const;
252         //@}
253
254         /** Implicit conversion to \ref Solvable */
255         operator const Solvable &() const { return _solv; }
256         /** \overload nonconst */
257         operator Solvable &() { return _solv; }
258
259       private:
260         Solvable _solv;
261         /** Pointer to implementation */
262         RW_pointer<Impl> _pimpl;
263     };
264
265     /** \relates Transaction::Step Stream output */
266     std::ostream & operator<<( std::ostream & str, const Transaction::Step & obj );
267
268     /** \relates Transaction::StepType Stream output */
269     std::ostream & operator<<( std::ostream & str, Transaction::StepType obj );
270
271     /** \relates Transaction::StepStage Stream output */
272     std::ostream & operator<<( std::ostream & str, Transaction::StepStage obj );
273
274    ///////////////////////////////////////////////////////////////////
275     namespace detail
276     { /////////////////////////////////////////////////////////////////
277
278       /** \ref Transaction iterator.
279        */
280       class Transaction_iterator : public boost::iterator_adaptor<
281       Transaction_iterator              // Derived
282       , const detail::IdType *          // Base
283       , Transaction::Step               // Value
284       , boost::forward_traversal_tag    // CategoryOrTraversal
285       , Transaction::Step               // Reference
286       >
287       {
288         public:
289           Transaction_iterator();
290           Transaction_iterator( const RW_pointer<Transaction::Impl> & pimpl_r, base_type id_r )
291           : Transaction_iterator::iterator_adaptor_( id_r )
292           , _pimpl( pimpl_r )
293           {}
294
295         private:
296           friend class boost::iterator_core_access;
297
298           reference dereference() const
299           { return Transaction::Step( _pimpl, *base() ); }
300
301         private:
302           friend class Transaction_const_iterator;
303           /** Pointer to implementation */
304           RW_pointer<Transaction::Impl> _pimpl;
305       };
306
307      /** \ref Transaction const_iterator.
308        */
309       class Transaction_const_iterator : public boost::iterator_adaptor<
310       Transaction_const_iterator        // Derived
311       , const detail::IdType *          // Base
312       , const Transaction::Step         // Value
313       , boost::forward_traversal_tag    // CategoryOrTraversal
314       , const Transaction::Step         // Reference
315       >
316       {
317         public:
318           Transaction_const_iterator();
319           Transaction_const_iterator( const Transaction_iterator & iter_r );
320           Transaction_const_iterator( const RW_pointer<Transaction::Impl> & pimpl_r, base_type id_r )
321           : Transaction_const_iterator::iterator_adaptor_( id_r )
322           , _pimpl( pimpl_r )
323           {}
324
325         private:
326           friend class boost::iterator_core_access;
327
328           reference dereference() const
329           { return Transaction::Step( _pimpl, *base() ); }
330
331         private:
332           /** Pointer to implementation */
333           RW_pointer<Transaction::Impl> _pimpl;
334       };
335
336        /////////////////////////////////////////////////////////////////
337     } // namespace detail
338     ///////////////////////////////////////////////////////////////////
339
340     inline Transaction::const_iterator Transaction::find( const ResObject::constPtr & resolvable_r ) const
341     { return( resolvable_r ? find( resolvable_r->satSolvable() ) : end() ); }
342
343     inline Transaction::iterator Transaction::find( const ResObject::constPtr & resolvable_r )
344     { return( resolvable_r ? find( resolvable_r->satSolvable() ) : end() ); }
345
346     inline Transaction::const_iterator Transaction::find( const PoolItem & pi_r ) const
347     { return find( pi_r.satSolvable() ); }
348
349     inline Transaction::iterator Transaction::find( const PoolItem & pi_r )
350     { return find( pi_r.satSolvable() ); }
351
352
353     struct  Transaction::FilterAction
354     {
355       FilterAction() {}
356       FilterAction( StepStages filter_r ) : _filter( filter_r ) {}
357
358       bool operator()( const Transaction::Step & step_r ) const
359       {
360         if ( step_r.stepType() == Transaction::TRANSACTION_IGNORE )
361           return false; // no action
362         return !_filter || _filter.testFlag( step_r.stepStage() );
363       }
364
365       StepStages _filter;
366     };
367
368     inline Transaction::action_iterator Transaction::actionBegin( StepStages filter_r ) const
369     { return make_filter_begin( FilterAction( filter_r ), *this ); }
370
371     inline Transaction::action_iterator Transaction::actionEnd() const
372     { return make_filter_end( FilterAction(), *this ); }
373
374     inline bool Transaction::actionEmpty( StepStages filter_r ) const
375     { return( actionBegin( filter_r ) == actionEnd() ); }
376
377     inline size_t Transaction::actionSize( StepStages filter_r ) const
378     {
379       size_t cnt = 0;
380       for_( it, actionBegin( filter_r ), actionEnd() )
381         ++cnt;
382       return cnt;
383     }
384
385      /////////////////////////////////////////////////////////////////
386   } // namespace sat
387   ///////////////////////////////////////////////////////////////////
388   /////////////////////////////////////////////////////////////////
389 } // namespace zypp
390 ///////////////////////////////////////////////////////////////////
391 #endif // ZYPP_SAT_TRANSACTION_H