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