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