1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/target/rpm/librpmDb.h
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"
32 ///////////////////////////////////////////////////////////////////
34 // CLASS NAME : librpmDb
36 * @short Manage access to librpm database.
38 class librpmDb : public base::ReferenceCounted, private base::NonCopyable
41 typedef intrusive_ptr<librpmDb> Ptr;
42 typedef intrusive_ptr<const librpmDb> constPtr;
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.
50 * \throws RpmException
53 static void dbAccess( librpmDb::Ptr & ptr_r );
57 ///////////////////////////////////////////////////////////////////
61 ///////////////////////////////////////////////////////////////////
65 * Current root directory for all operations.
68 static Pathname _defaultRoot;
71 * Current directory (below root) that contains the rpmdb.
72 * (initialy /var/lib/rpm)
74 static const Pathname _defaultDbPath;
77 * Current rpmdb handle.
79 static librpmDb::constPtr _defaultDb;
82 * Whether access is blocked (no _defaultDb will be available).
84 static bool _dbBlocked;
87 * For internal use. Pointer returned should immediately be
88 * wrapped into librpmDb::Ptr.
90 * \throws RpmException
93 static librpmDb * newLibrpmDb();
96 * Access the database at the current default location. If necessary
97 * (eg. after @ref dbRelease), the database is opened. This just creates
98 * the internal handle. Once the handle is passed to e.g. some
99 * @ref db_const_iterator, the database will be closed if the last
100 * outstanding reference goes out of scope. If no external reference is
101 * created, you'll have to explicitly call @ref dbRelease to close the
104 * \throws RpmException
107 static void dbAccess();
112 * Initialize lib librpm (read configfiles etc.). It's called
113 * on demand but you may call it anytime.
115 * @return Whether librpm is initialized.
117 static bool globalInit();
120 * @return librpm macro expansion.
122 static std::string expand( const std::string & macro_r );
125 * @return String '(root_r)sub_r' used in debug output.
127 static std::string stringPath( const Pathname & root_r, const Pathname & sub_r )
129 return std::string( "'(" ) + root_r.asString() + ")" + sub_r.asString() + "'";
135 * @return Current root directory for all operations.
137 static const Pathname & defaultRoot()
143 * @return Current directory (below root) that contains the rpmdb.
145 static const Pathname & defaultDbPath()
147 return _defaultDbPath;
151 * Adjust access to the given database location, making it the new
152 * default location on success. No relative Pathnames are allowed.
154 * It's not possible to access a database while access is blocked
155 * (see @ref blockAccess), but valid Pathnames provided will be stored
156 * as new default location.
158 * It's not allowed to switch to another location while a database
159 * is accessed. Use @ref dbRelease to force releasing the database first.
161 * \throws RpmException
164 static void dbAccess( const Pathname & root_r );
167 * Same as &ref dbAccess(), but returns the database handle if
168 * avaialble, otherwise NULL. This creates an external reference, thus
169 * it should not be used longer than necessary. Be prepared that the
170 * handle might become invalid (see @ref dbRelease) later.
172 * \throws RpmException
175 static void dbAccess( librpmDb::constPtr & ptr_r );
178 * If there are no outstanding references to the database (e.g. by @ref db_const_iterator),
179 * the database is closed. Subsequent calls to @ref dbAccess may however
180 * open the database again.
182 * If forced, the internal reference is dropped and it will look like
183 * the database was closed. But physically the database will be closed
184 * after all outstanding references are gone.
186 * @return The number of outstandig references to the database, 0 if
187 * if database was physically closed.
189 static unsigned dbRelease( bool force_r = false );
192 * Blocks further access to rpmdb. Basically the same as @ref dbRelease( true ),
193 * but subsequent calls to @ref dbAccess will fail returning E_RpmDB_access_blocked.
195 * @return The number of outstandig references to the database, 0 if
196 * if database was physically closed.
198 static unsigned blockAccess();
201 * Allow access to rpmdb e.g. after @ref blockAccess. Subsequent calls to
202 * @ref dbAccess will perform.
204 * <B>NOTE:</B> Initially we're in blocked mode. So you must call @ref unblockAccess
205 * unblockAccess at least once. Othwise nothing will happen.
207 * @return The number of outstandig references to the database, 0 if
208 * if database was physically closed.
210 static void unblockAccess();
213 * @return Whether database access is blocked.
215 static bool isBlocked()
223 static std::ostream & dumpState( std::ostream & str );
228 * Subclass to retrieve database content.
230 class db_const_iterator;
233 ///////////////////////////////////////////////////////////////////
235 // internal database handle interface (nonstatic)
237 ///////////////////////////////////////////////////////////////////
240 * Hides librpm specific data
248 * Private constructor! librpmDb objects are to be created via
249 * static interface only.
251 librpmDb( const Pathname & root_r, const Pathname & dbPath_r, bool readonly_r );
254 * Trigger from @ref Rep, after refCount was decreased.
256 virtual void unref_to( unsigned refCount_r ) const;
261 * Destructor. Closes rpmdb.
266 * @return This handles root directory for all operations.
268 const Pathname & root() const;
271 * @return This handles directory that contains the rpmdb.
273 const Pathname & dbPath() const;
276 * Return any database error. Usg. if the database was
277 * blocked by calling @ref dbRelease(true) or @ref blockAccess.
279 shared_ptr<RpmException> error() const;
282 * @return Whether handle is valid.
290 * @return True if handle is valid and database is empty.
295 * @return Number of entries in the database (0 if not valid).
297 unsigned size() const;
302 * Dont call it ;) It's for development and testing only.
304 void * dont_call_it() const;
309 virtual std::ostream & dumpOn( std::ostream & str ) const;
312 ///////////////////////////////////////////////////////////////////
314 ///////////////////////////////////////////////////////////////////
316 // CLASS NAME : librpmDb::db_const_iterator
318 * @short Subclass to retrieve database content.
322 class librpmDb::db_const_iterator
324 db_const_iterator & operator=( const db_const_iterator & ); // NO ASSIGNMENT!
325 db_const_iterator ( const db_const_iterator & ); // NO COPY!
326 friend std::ostream & operator<<( std::ostream & str, const db_const_iterator & obj );
327 friend class librpmDb;
332 * Hides librpm specific data
340 * Constructor. Iterator is initialized to @ref findAll.
341 * The default form accesses librpmDb's default database.
342 * Explicitly providing a database handle should not be
343 * neccesary, except for testing.
345 db_const_iterator( librpmDb::constPtr dbptr_r = 0 );
350 ~db_const_iterator();
353 * Return any database error.
355 * <B>NOTE:</B> If the database gets blocked (see @ref dbRelease)
356 * dbError will immediately report this, but an already running
357 * iteration will proceed to its end. Then the database is dropped.
359 shared_ptr<RpmException> dbError() const;
362 * Advance to next RpmHeader::constPtr.
367 * Returns the current headers index in database,
370 unsigned dbHdrNum() const;
373 * Returns the current RpmHeader::constPtr or
374 * NULL, if no more entries available.
376 const RpmHeader::constPtr & operator*() const;
379 * Forwards to the current RpmHeader::constPtr.
381 const RpmHeader::constPtr & operator->() const
389 * Reset to iterate all packages. Returns true if iterator
390 * contains at least one entry.
392 * <B>NOTE:</B> No entry (false) migt be returned due to a
393 * meanwhile blocked database (see @ref dbRelease). Use
394 * @ref dbError to check this.
399 * Reset to iterate all packages that own a certain file.
401 bool findByFile( const std::string & file_r );
404 * Reset to iterate all packages that provide a certain tag.
406 bool findByProvides( const std::string & tag_r );
409 * Reset to iterate all packages that require a certain tag.
411 bool findByRequiredBy( const std::string & tag_r );
414 * Reset to iterate all packages that conflict with a certain tag.
416 bool findByConflicts( const std::string & tag_r );
419 * Reset to iterate all packages with a certain name.
421 * <B>NOTE:</B> Multiple entries for one package installed
422 * in different versions are possible but not desired. Usually
423 * you'll want to use @ref findPackage instead.
425 * findByName is needed to retrieve pseudo packages like
426 * 'gpg-pubkey', which in fact exist in multiple instances.
428 bool findByName( const std::string & name_r );
433 * Find package by name.
435 * Multiple entries for one package installed in different versions
436 * are possible but not desired. If so, the last package installed
439 bool findPackage( const std::string & name_r );
442 * Find package by name and edition.
443 * Commonly used by PMRpmPackageDataProvider.
445 bool findPackage( const std::string & name_r, const Edition & ed_r );
448 * Abbr. for <code>findPackage( which_r->name(), which_r->edition() );</code>
450 bool findPackage( const Package::constPtr & which_r );
453 ///////////////////////////////////////////////////////////////////