Imported Upstream version 17.25.3
[platform/upstream/libzypp.git] / zypp / target / rpm / librpmDb.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/target/rpm/librpmDb.h
10  *
11 */
12 #ifndef librpmDb_h
13 #define librpmDb_h
14
15 #include <iosfwd>
16
17 #include <zypp/base/ReferenceCounted.h>
18 #include <zypp/base/NonCopyable.h>
19 #include <zypp/base/PtrTypes.h>
20 #include <zypp/PathInfo.h>
21 #include <zypp/Package.h>
22 #include <zypp/target/rpm/RpmHeader.h>
23 #include <zypp/target/rpm/RpmException.h>
24
25 namespace zypp
26 {
27 namespace target
28 {
29 namespace rpm
30 {
31
32 ///////////////////////////////////////////////////////////////////
33 //
34 //      CLASS NAME : librpmDb
35 /**
36  * @short Manage access to librpm database.
37  **/
38 class librpmDb : public base::ReferenceCounted, private base::NonCopyable
39 {
40 public:
41   typedef intrusive_ptr<librpmDb> Ptr;
42   typedef intrusive_ptr<const librpmDb> constPtr;
43 private:
44   /**
45    * <B>INTENTIONALLY UNDEFINED<\B> because of bug in Ptr classes
46    * which allows implicit conversion from librpmDb::Ptr to
47    * librpmDb::constPtr. Currently we don't want to provide non const
48    * handles, as the database is opened READONLY.
49   *
50    * \throws RpmException
51    *
52    **/
53   static void dbAccess( librpmDb::Ptr & ptr_r );
54
55 public:
56
57   ///////////////////////////////////////////////////////////////////
58   //
59   //    static interface
60   //
61   ///////////////////////////////////////////////////////////////////
62 private:
63
64   /**
65    * Current root directory for all operations.
66    * (initially /)
67    **/
68   static Pathname _defaultRoot;
69
70   /**
71    * Current directory (below root) that contains the rpmdb.
72    **/
73   static Pathname _defaultDbPath;
74
75   /**
76    * %_dbpath configured in rpm config.
77    **/
78   static Pathname _rpmDefaultDbPath;
79
80   /**
81    * Current rpmdb handle.
82    **/
83   static librpmDb::constPtr _defaultDb;
84
85   /**
86    * Whether access is blocked (no _defaultDb will be available).
87    **/
88   static bool _dbBlocked;
89
90   /**
91    * For internal use. Pointer returned should immediately be
92    * wrapped into librpmDb::Ptr.
93    *
94    * \throws RpmException
95    *
96    **/
97   static librpmDb * newLibrpmDb();
98
99   /**
100    * Access the database at the current default location. If necessary
101    * (eg. after @ref dbRelease), the database is opened. This just creates
102    * the internal handle. Once the handle is passed to e.g. some
103    * @ref db_const_iterator, the database will be closed if the last
104    * outstanding reference goes out of scope. If no external reference is
105    * created, you'll have to explicitly call @ref dbRelease to close the
106    * database.
107    *
108    * \throws RpmException
109    *
110    **/
111   static void dbAccess();
112
113 public:
114
115   /**
116    * Initialize lib librpm (read configfiles etc.). It's called
117    * on demand but you may call it anytime.
118    *
119    * @return Whether librpm is initialized.
120    **/
121   static bool globalInit();
122
123   /**
124    * @return librpm macro expansion.
125    **/
126   static std::string expand( const std::string & macro_r );
127
128   /**
129    * @return String '(root_r)sub_r' used in debug output.
130    **/
131   static std::string stringPath( const Pathname & root_r, const Pathname & sub_r )
132   {
133     return std::string( "'(" ) + root_r.asString() + ")" + sub_r.asString() + "'";
134   }
135
136 public:
137
138   /**
139    * @return Current root directory for all operations.
140    **/
141   static const Pathname & defaultRoot()
142   {
143     return _defaultRoot;
144   }
145
146   /**
147    * @return Current directory (below root) that contains the rpmdb.
148    **/
149   static const Pathname & defaultDbPath()
150   {
151     return _defaultDbPath;
152   }
153
154   /**
155    * \return The preferred location of the rpmdb below \a root_r.
156    * It's the location of an already exising db, otherwise the
157    * default location sugested by rpms config.
158    *
159    * \throws RpmInvalidRootException if root is not an absolute path or
160    * no directory for the rpmdb can determined.
161    **/
162   static Pathname suggestedDbPath( const Pathname & root_r );
163
164   /**
165    * Adjust access to the given database location, making it the new
166    * default location on success. No relative Pathnames are allowed.
167    *
168    * It's not possible to access a database while access is blocked
169    * (see @ref blockAccess), but valid Pathnames provided will be stored
170    * as new default location.
171    *
172    * It's not allowed to switch to another location while a database
173    * is accessed. Use @ref dbRelease to force releasing the database first.
174   *
175    * \throws RpmException
176    *
177    **/
178   static void dbAccess( const Pathname & root_r );
179
180   /**
181    * Same as &ref dbAccess(), but returns the database handle if
182    * avaialble, otherwise NULL. This creates an external reference, thus
183    * it should not be used longer than necessary. Be prepared that the
184    * handle might become invalid (see @ref dbRelease) later.
185    *
186    * \throws RpmException
187    *
188    **/
189   static void dbAccess( librpmDb::constPtr & ptr_r );
190
191   /**
192    * If there are no outstanding references to the database (e.g. by @ref db_const_iterator),
193    * the database is closed. Subsequent calls to @ref dbAccess may however
194    * open the database again.
195    *
196    * If forced, the internal reference is dropped and it will look like
197    * the database was closed. But physically the database will be closed
198    * after all outstanding references are gone.
199    *
200    * @return The number of outstandig references to the database, 0 if
201    * if database was physically closed.
202    **/
203   static unsigned dbRelease( bool force_r = false );
204
205   /**
206    * Blocks further access to rpmdb. Basically the same as @ref dbRelease( true ),
207    * but subsequent calls to @ref dbAccess will fail returning E_RpmDB_access_blocked.
208    *
209    * @return The number of outstandig references to the database, 0 if
210    * if database was physically closed.
211    **/
212   static unsigned blockAccess();
213
214   /**
215    * Allow access to rpmdb e.g. after @ref blockAccess. Subsequent calls to
216    * @ref dbAccess will perform.
217    *
218    * <B>NOTE:</B> Initially we're in blocked mode. So you must call @ref unblockAccess
219    * unblockAccess at least once. Othwise nothing will happen.
220    *
221    * @return The number of outstandig references to the database, 0 if
222    * if database was physically closed.
223    **/
224   static void unblockAccess();
225
226   /**
227    * @return Whether database access is blocked.
228    **/
229   static bool isBlocked()
230   {
231     return _dbBlocked;
232   }
233
234   /**
235    * Dump debug info.
236    **/
237   static std::ostream & dumpState( std::ostream & str );
238
239 public:
240
241   /**
242    * Subclass to retrieve database content.
243    **/
244   class db_const_iterator;
245
246 private:
247   ///////////////////////////////////////////////////////////////////
248   //
249   //    internal database handle interface (nonstatic)
250   //
251   ///////////////////////////////////////////////////////////////////
252
253   /**
254    * Hides librpm specific data
255    **/
256   class D;
257   D & _d;
258
259 protected:
260
261   /**
262    * Private constructor! librpmDb objects are to be created via
263    * static interface only.
264    **/
265   librpmDb( const Pathname & root_r, const Pathname & dbPath_r, bool readonly_r );
266
267   /**
268    * Trigger from @ref Rep, after refCount was decreased.
269    **/
270   virtual void unref_to( unsigned refCount_r ) const;
271
272 public:
273
274   /**
275    * Destructor. Closes rpmdb.
276    **/
277   virtual ~librpmDb();
278
279   /**
280    * @return This handles root directory for all operations.
281    **/
282   const Pathname & root() const;
283
284   /**
285    * @return This handles directory that contains the rpmdb.
286    **/
287   const Pathname & dbPath() const;
288
289   /**
290    * Return any database error. Usg. if the database was
291    * blocked by calling @ref dbRelease(true) or @ref blockAccess.
292    **/
293   shared_ptr<RpmException> error() const;
294
295   /**
296    * @return Whether handle is valid.
297    **/
298   bool valid() const
299   {
300     return( ! error() );
301   }
302
303   /**
304    * @return True if handle is valid and database is empty.
305    **/
306   bool empty() const;
307
308   /**
309    * @return Number of entries in the database (0 if not valid).
310    **/
311   unsigned size() const;
312
313 public:
314
315   /**
316    * Dont call it ;) It's for development and testing only.
317    **/
318   void * dont_call_it() const;
319
320   /**
321    * Dump debug info.
322    **/
323   virtual std::ostream & dumpOn( std::ostream & str ) const;
324 };
325
326 ///////////////////////////////////////////////////////////////////
327
328 ///////////////////////////////////////////////////////////////////
329 //
330 //      CLASS NAME : librpmDb::db_const_iterator
331 /**
332  * @short Subclass to retrieve database content.
333  *
334  *
335  **/
336 class librpmDb::db_const_iterator
337 {
338   db_const_iterator & operator=( const db_const_iterator & ); // NO ASSIGNMENT!
339   db_const_iterator ( const db_const_iterator & );            // NO COPY!
340   friend std::ostream & operator<<( std::ostream & str, const db_const_iterator & obj );
341   friend class librpmDb;
342
343 private:
344
345   /**
346    * Hides librpm specific data
347    **/
348   class D;
349   D & _d;
350
351 public:
352
353   /**
354    * Constructor. Iterator is initialized to @ref findAll.
355    * The default form accesses librpmDb's default database.
356    * Explicitly providing a database handle should not be
357    * neccesary, except for testing.
358    **/
359   db_const_iterator( librpmDb::constPtr dbptr_r = 0 );
360
361   /**
362    * Destructor.
363    **/
364   ~db_const_iterator();
365
366   /**
367    * Return any database error.
368    *
369    * <B>NOTE:</B> If the database gets blocked (see @ref dbRelease)
370    * dbError will immediately report this, but an already running
371    * iteration will proceed to its end. Then the database is dropped.
372    **/
373   shared_ptr<RpmException> dbError() const;
374
375   /**
376    * Advance to next RpmHeader::constPtr.
377    **/
378   void operator++();
379
380   /**
381    * Returns the current headers index in database,
382    * 0 if no header.
383    **/
384   unsigned dbHdrNum() const;
385
386   /**
387    * Returns the current RpmHeader::constPtr or
388    * NULL, if no more entries available.
389    **/
390   const RpmHeader::constPtr & operator*() const;
391
392   /**
393    * Forwards to the current RpmHeader::constPtr.
394    **/
395   const RpmHeader::constPtr & operator->() const
396   {
397     return operator*();
398   }
399
400 public:
401
402   /**
403    * Reset to iterate all packages. Returns true if iterator
404    * contains at least one entry.
405    *
406    * <B>NOTE:</B> No entry (false) migt be returned due to a
407    * meanwhile blocked database (see @ref dbRelease). Use
408    * @ref dbError to check this.
409    **/
410   bool findAll();
411
412   /**
413    * Reset to iterate all packages that own a certain file.
414    **/
415   bool findByFile( const std::string & file_r );
416
417   /**
418    * Reset to iterate all packages that provide a certain tag.
419    **/
420   bool findByProvides( const std::string & tag_r );
421
422   /**
423    * Reset to iterate all packages that require a certain tag.
424    **/
425   bool findByRequiredBy( const std::string & tag_r );
426
427   /**
428    * Reset to iterate all packages that conflict with a certain tag.
429    **/
430   bool findByConflicts( const std::string & tag_r );
431
432   /**
433    * Reset to iterate all packages with a certain name.
434    *
435    * <B>NOTE:</B> Multiple entries for one package installed
436    * in different versions are possible but not desired. Usually
437    * you'll want to use @ref findPackage instead.
438    *
439    * findByName is needed to retrieve pseudo packages like
440    * 'gpg-pubkey', which in fact exist in multiple instances.
441    **/
442   bool findByName( const std::string & name_r );
443
444 public:
445
446   /**
447    * Find package by name.
448    *
449    * Multiple entries for one package installed in different versions
450    * are possible but not desired. If so, the last package installed
451    * is returned.
452    **/
453   bool findPackage( const std::string & name_r );
454
455   /**
456    * Find package by name and edition.
457    * Commonly used by PMRpmPackageDataProvider.
458    **/
459   bool findPackage( const std::string & name_r, const Edition & ed_r );
460
461   /**
462    * Abbr. for <code>findPackage( which_r->name(), which_r->edition() );</code>
463    **/
464   bool findPackage( const Package::constPtr & which_r );
465 };
466
467 ///////////////////////////////////////////////////////////////////
468 } //namespace rpm
469 } //namespace target
470 } // namespace zypp
471
472 #endif // librpmDb_h
473