Imported Upstream version 17.23.0
[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         /** Iterate the [filtered] transaction steps. */
169         Iterable<action_iterator> action( StepStages filter_r = StepStages() ) const;
170         //@}
171
172       public:
173         /** Return all packages that would be installed after the transaction is run.
174          * The new packages are put at the head of the queue, the number of new
175          * packages is returned. (wraps libsolv::transaction_installedresult) */
176         int installedResult( Queue & result_r ) const;
177
178         /** Return the ident strings of all packages that would be auto-installed after the transaction is run. */
179         StringQueue autoInstalled() const;
180
181         /** Set the ident strings of all packages that would be auto-installed after the transaction is run. */
182         void autoInstalled( const StringQueue & queue_r );
183
184       public:
185         /** Implementation  */
186         struct Impl;
187       private:
188         /** Pointer to implementation */
189         RW_pointer<Impl> _pimpl;
190     };
191
192     ZYPP_DECLARE_OPERATORS_FOR_FLAGS(Transaction::StepStages);
193
194     /** \relates Transaction Stream output */
195     std::ostream & operator<<( std::ostream & str, const Transaction & obj );
196
197     /** \relates Transaction Verbose stream output */
198     std::ostream & dumpOn( std::ostream & str, const Transaction & obj );
199
200     /** \relates Transaction */
201     bool operator==( const Transaction & lhs, const Transaction & rhs );
202
203     /** \relates Transaction */
204     inline bool operator!=( const Transaction & lhs, const Transaction & rhs )
205     { return !( lhs == rhs ); }
206
207
208     /** A single step within a \ref Transaction.
209      *
210      * \note After commit, when the @System repo (rpm database) is reread, all
211      * @System solvables within the transaction are invalidated (they got deleted).
212      * Thats why we internally store the NVRA, so you can access \ref ident
213      * (\see \ref sat::Solvable::ident), \ref edition, \ref arch of a deleted package,
214      * even if the \ref satSolvable itself is meanwhile invalid.
215      *
216      * \see \ref Transaction.
217      */
218     class Transaction::Step
219     {
220       friend std::ostream & operator<<( std::ostream & str, const Step & obj );
221
222       public:
223         Step();
224         Step( const RW_pointer<Impl> & pimpl_r, detail::IdType id_r )
225           : _solv( id_r )
226           , _pimpl( pimpl_r )
227         {}
228
229       public:
230         /** Type of action to perform in this step. */
231         StepType stepType() const;
232
233         /** Step action result. */
234         StepStage stepStage() const;
235
236         /** Set step action result. */
237         void stepStage( StepStage val_r );
238
239         /** Return the corresponding \ref Solvable.
240          * Returns \ref Solvable::noSolvable if the item is meanwhile deleted and
241          * was removed from the pool. \see Post mortem acccess to @System solvables.
242          */
243         Solvable satSolvable() const
244         { return _solv; }
245
246         /** \name Post mortem acccess to @System solvables
247          * \code
248          *   Transaction::Step step;
249          *   if ( step.satSolvable() )
250          *     std::cout << step.satSolvable() << endl;
251          *   else
252          *     std::cout << step.ident() << endl; // deleted @System solvable
253          * \endcode
254          */
255         //@{
256         /** \see \ref sat::Solvable::ident. */
257         IdString ident() const;
258
259         /** \see \ref sat::Solvable::edition. */
260         Edition edition() const;
261
262         /** \see \ref sat::Solvable::arch. */
263         Arch arch() const;
264         //@}
265
266         /** Implicit conversion to \ref Solvable */
267         operator const Solvable &() const { return _solv; }
268         /** \overload nonconst */
269         operator Solvable &() { return _solv; }
270
271       private:
272         Solvable _solv;
273         /** Pointer to implementation */
274         RW_pointer<Impl> _pimpl;
275     };
276
277     /** \relates Transaction::Step Stream output */
278     std::ostream & operator<<( std::ostream & str, const Transaction::Step & obj );
279
280     /** \relates Transaction::StepType Stream output */
281     std::ostream & operator<<( std::ostream & str, Transaction::StepType obj );
282
283     /** \relates Transaction::StepStage Stream output */
284     std::ostream & operator<<( std::ostream & str, Transaction::StepStage obj );
285
286    ///////////////////////////////////////////////////////////////////
287     namespace detail
288     { /////////////////////////////////////////////////////////////////
289
290       /** \ref Transaction iterator.
291        */
292       class Transaction_iterator : public boost::iterator_adaptor<
293       Transaction_iterator              // Derived
294       , const detail::IdType *          // Base
295       , Transaction::Step               // Value
296       , boost::forward_traversal_tag    // CategoryOrTraversal
297       , Transaction::Step               // Reference
298       >
299       {
300         public:
301           Transaction_iterator();
302           Transaction_iterator( const RW_pointer<Transaction::Impl> & pimpl_r, base_type id_r )
303           : Transaction_iterator::iterator_adaptor_( id_r )
304           , _pimpl( pimpl_r )
305           {}
306
307         private:
308           friend class boost::iterator_core_access;
309
310           reference dereference() const
311           { return Transaction::Step( _pimpl, *base() ); }
312
313         private:
314           friend class Transaction_const_iterator;
315           /** Pointer to implementation */
316           RW_pointer<Transaction::Impl> _pimpl;
317       };
318
319      /** \ref Transaction const_iterator.
320        */
321       class Transaction_const_iterator : public boost::iterator_adaptor<
322       Transaction_const_iterator        // Derived
323       , const detail::IdType *          // Base
324       , const Transaction::Step         // Value
325       , boost::forward_traversal_tag    // CategoryOrTraversal
326       , const Transaction::Step         // Reference
327       >
328       {
329         public:
330           Transaction_const_iterator();
331           Transaction_const_iterator( const Transaction_iterator & iter_r );
332           Transaction_const_iterator( const RW_pointer<Transaction::Impl> & pimpl_r, base_type id_r )
333           : Transaction_const_iterator::iterator_adaptor_( id_r )
334           , _pimpl( pimpl_r )
335           {}
336
337         private:
338           friend class boost::iterator_core_access;
339
340           reference dereference() const
341           { return Transaction::Step( _pimpl, *base() ); }
342
343         private:
344           /** Pointer to implementation */
345           RW_pointer<Transaction::Impl> _pimpl;
346       };
347
348        /////////////////////////////////////////////////////////////////
349     } // namespace detail
350     ///////////////////////////////////////////////////////////////////
351
352     inline Transaction::const_iterator Transaction::find( const ResObject::constPtr & resolvable_r ) const
353     { return( resolvable_r ? find( resolvable_r->satSolvable() ) : end() ); }
354
355     inline Transaction::iterator Transaction::find( const ResObject::constPtr & resolvable_r )
356     { return( resolvable_r ? find( resolvable_r->satSolvable() ) : end() ); }
357
358     inline Transaction::const_iterator Transaction::find( const PoolItem & pi_r ) const
359     { return find( pi_r.satSolvable() ); }
360
361     inline Transaction::iterator Transaction::find( const PoolItem & pi_r )
362     { return find( pi_r.satSolvable() ); }
363
364
365     struct  Transaction::FilterAction
366     {
367       FilterAction() {}
368       FilterAction( StepStages filter_r ) : _filter( filter_r ) {}
369
370       bool operator()( const Transaction::Step & step_r ) const
371       {
372         if ( step_r.stepType() == Transaction::TRANSACTION_IGNORE )
373           return false; // no action
374         return !_filter || _filter.testFlag( step_r.stepStage() );
375       }
376
377       StepStages _filter;
378     };
379
380     inline Transaction::action_iterator Transaction::actionBegin( StepStages filter_r ) const
381     { return make_filter_begin( FilterAction( filter_r ), *this ); }
382
383     inline Transaction::action_iterator Transaction::actionEnd() const
384     { return make_filter_end( FilterAction(), *this ); }
385
386     inline bool Transaction::actionEmpty( StepStages filter_r ) const
387     { return( actionBegin( filter_r ) == actionEnd() ); }
388
389     inline size_t Transaction::actionSize( StepStages filter_r ) const
390     {
391       size_t cnt = 0;
392       for_( it, actionBegin( filter_r ), actionEnd() )
393         ++cnt;
394       return cnt;
395     }
396
397     inline Iterable<Transaction::action_iterator> Transaction::action( StepStages filter_r ) const
398     { return makeIterable( actionBegin( filter_r ), actionEnd() ); }
399
400      /////////////////////////////////////////////////////////////////
401   } // namespace sat
402   ///////////////////////////////////////////////////////////////////
403   /////////////////////////////////////////////////////////////////
404 } // namespace zypp
405 ///////////////////////////////////////////////////////////////////
406 #endif // ZYPP_SAT_TRANSACTION_H