librpmDb.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include "librpm.h"
00013 
00014 #include <iostream>
00015 
00016 #include "zypp/base/Logger.h"
00017 #include "zypp/target/rpm/librpmDb.h"
00018 #include "zypp/target/rpm/RpmHeader.h"
00019 #include "zypp/target/rpm/RpmException.h"
00020 
00021 using namespace std;
00022 
00023 namespace zypp {
00024   namespace target {
00025     namespace rpm {
00027 //
00028 //      CLASS NAME : librpmDb::D
00032 class librpmDb::D {
00033   D & operator=( const D & ); // NO ASSIGNMENT!
00034   D ( const D & );            // NO COPY!
00035   public:
00036 
00037     const Pathname _root;   // root directory for all operations
00038     const Pathname _dbPath; // directory (below root) that contains the rpmdb
00039     rpmdb          _db;     // database handle
00040     shared_ptr<RpmException> _error;  // database error
00041 
00042     friend ostream & operator<<( ostream & str, const D & obj ) {
00043       str << "{" << obj._error  << "(" << obj._root << ")" << obj._dbPath << "}";
00044       return str;
00045     }
00046 
00047     D( const Pathname & root_r, const Pathname & dbPath_r, bool readonly_r )
00048       : _root  ( root_r )
00049       , _dbPath( dbPath_r )
00050       , _db    ( 0 )
00051     {
00052       _error.reset();
00053       // set %_dbpath macro
00054       ::addMacro( NULL, "_dbpath", NULL, _dbPath.asString().c_str(), RMIL_CMDLINE );
00055       const char * root = ( _root == "/" ? NULL : _root.asString().c_str() );
00056       int          perms = 0644;
00057 
00058       // check whether to create a new db
00059       PathInfo master( _root + _dbPath + "Packages" );
00060       if ( ! master.isFile() ) {
00061         // init database
00062         int res = ::rpmdbInit( root, perms );
00063         if ( res ) {
00064           ERR << "rpmdbInit error(" << res << "): " << *this << endl;
00065           _error = shared_ptr<RpmInitException>(new RpmInitException(_root, _dbPath));
00066           ZYPP_THROW(*_error);
00067         }
00068       }
00069 
00070       // open database
00071       int res = ::rpmdbOpen( root, &_db, (readonly_r ? O_RDONLY : O_RDWR ), perms );
00072       if ( res || !_db ) {
00073         if ( _db ) {
00074           ::rpmdbClose( _db );
00075           _db = 0;
00076         }
00077         ERR << "rpmdbOpen error(" << res << "): " << *this << endl;
00078         _error = shared_ptr<RpmDbOpenException>(new RpmDbOpenException(_root, _dbPath));
00079         ZYPP_THROW(*_error);
00080         return;
00081       }
00082 
00083       DBG << "DBACCESS " << *this << endl;
00084     }
00085 
00086     ~D() {
00087       if ( _db ) {
00088       ::rpmdbClose( _db );
00089       }
00090     }
00091 };
00092 
00094 
00096 //
00097 //      CLASS NAME : librpmDb (ststic interface)
00098 //
00100 
00101 Pathname         librpmDb::_defaultRoot  ( "/" );
00102 Pathname         librpmDb::_defaultDbPath( "/var/lib/rpm" );
00103 librpmDb::constPtr librpmDb::_defaultDb;
00104 bool             librpmDb::_dbBlocked    ( true );
00105 
00107 //
00108 //
00109 //      METHOD NAME : librpmDb::globalInit
00110 //      METHOD TYPE : bool
00111 //
00112 bool librpmDb::globalInit()
00113 {
00114   static bool initialized = false;
00115 
00116   if ( initialized )
00117     return true;
00118 
00119   int rc = ::rpmReadConfigFiles( NULL, NULL );
00120   if ( rc ) {
00121     ERR << "rpmReadConfigFiles returned " << rc << endl;
00122     return false;
00123   }
00124 
00125   // should speed up convertdb and rebuilddb.
00126   ::addMacro( NULL, "_rpmdb_rebuild", NULL, "%{nil}", RMIL_CMDLINE );
00127 
00128   initialized = true; // Necessary to be able to use exand().
00129 
00130 #define OUTVAL(n) << " (" #n ":" << expand( "%{" #n "}" ) << ")"
00131   MIL << "librpm init done:"
00132     OUTVAL(_target)
00133     OUTVAL(_dbpath)
00134       << endl;
00135 #undef OUTVAL
00136   return initialized;
00137 }
00138 
00140 //
00141 //
00142 //      METHOD NAME : librpmDb::expand
00143 //      METHOD TYPE : std::string
00144 //
00145 std::string librpmDb::expand( const std::string & macro_r )
00146 {
00147   if ( ! globalInit() )
00148     return macro_r;  // unexpanded
00149 
00150   char * val = ::rpmExpand( macro_r.c_str(), NULL );
00151   if ( !val )
00152     return "";
00153 
00154   string ret( val );
00155   free( val );
00156   return ret;
00157 }
00158 
00160 //
00161 //
00162 //      METHOD NAME : librpmDb::newLibrpmDb
00163 //      METHOD TYPE : librpmDb *
00164 //
00165 librpmDb * librpmDb::newLibrpmDb( Pathname root_r, Pathname dbPath_r, bool readonly_r )
00166 {
00167   // check arguments
00168   if ( ! (root_r.absolute() && dbPath_r.absolute()) ) {
00169     ZYPP_THROW(RpmInvalidRootException(root_r, dbPath_r));
00170   }
00171 
00172   // initialize librpm
00173   if ( ! globalInit() ) {
00174     ZYPP_THROW(GlobalRpmInitException());
00175   }
00176 
00177   // open rpmdb
00178   librpmDb * ret = 0;
00179   try {
00180     ret = new librpmDb( root_r, dbPath_r, readonly_r );
00181   }
00182   catch (const RpmException & excpt_r)
00183   {
00184     ZYPP_CAUGHT(excpt_r);
00185     delete ret;
00186     ret = 0;
00187     ZYPP_RETHROW(excpt_r);
00188   }
00189   return ret;
00190 }
00191 
00193 //
00194 //
00195 //      METHOD NAME : librpmDb::dbAccess
00196 //      METHOD TYPE : PMError
00197 //
00198 void librpmDb::dbAccess( const Pathname & root_r, const Pathname & dbPath_r )
00199 {
00200   // check arguments
00201   if ( ! (root_r.absolute() && dbPath_r.absolute()) ) {
00202     ZYPP_THROW(RpmInvalidRootException(root_r, dbPath_r));
00203   }
00204 
00205   if ( _defaultDb ) {
00206     // already accessing a database: switching is not allowed.
00207     if ( _defaultRoot == root_r && _defaultDbPath == dbPath_r )
00208       return;
00209     else {
00210       ZYPP_THROW(RpmDbAlreadyOpenException(_defaultRoot, _defaultDbPath, root_r, dbPath_r));
00211     }
00212   }
00213 
00214   // got no database: we could switch to a new one (even if blocked!)
00215   _defaultRoot = root_r;
00216   _defaultDbPath = dbPath_r;
00217   MIL << "Set new database location: " << stringPath( _defaultRoot, _defaultDbPath ) << endl;
00218 
00219   return dbAccess();
00220 }
00221 
00223 //
00224 //
00225 //      METHOD NAME : librpmDb::dbAccess
00226 //      METHOD TYPE : PMError
00227 //
00228 void librpmDb::dbAccess()
00229 {
00230   if ( _dbBlocked ) {
00231     ZYPP_THROW(RpmAccessBlockedException(_defaultRoot, _defaultDbPath));
00232   }
00233 
00234   if ( !_defaultDb ) {
00235     // get access
00236     _defaultDb = newLibrpmDb( _defaultRoot, _defaultDbPath, /*readonly*/true );
00237   }
00238 }
00239 
00241 //
00242 //
00243 //      METHOD NAME : librpmDb::dbAccess
00244 //      METHOD TYPE : PMError
00245 //
00246 void librpmDb::dbAccess( librpmDb::constPtr & ptr_r )
00247 {
00248   try {
00249     dbAccess();
00250   }
00251   catch (const RpmException & excpt_r)
00252   {
00253     ZYPP_CAUGHT(excpt_r);
00254     ptr_r = 0;
00255     ZYPP_RETHROW(excpt_r);
00256   }
00257   ptr_r = _defaultDb;
00258 }
00259 
00261 //
00262 //
00263 //      METHOD NAME : librpmDb::dbRelease
00264 //      METHOD TYPE : unsigned
00265 //
00266 unsigned librpmDb::dbRelease( bool force_r )
00267 {
00268   if ( !_defaultDb ) {
00269     return 0;
00270   }
00271 
00272   unsigned outstanding = _defaultDb->refCount() - 1; // refCount can't be 0
00273 
00274   switch ( outstanding ) {
00275   default:
00276     if ( !force_r ) {
00277       DBG << "dbRelease: keep access, outstanding " << outstanding << endl;
00278       break;
00279     }
00280     // else fall through:
00281   case 0:
00282     DBG << "dbRelease: release" << (force_r && outstanding ? "(forced)" : "")
00283       << ", outstanding " << outstanding << endl;
00284 
00285     _defaultDb->_d._error = shared_ptr<RpmAccessBlockedException>(new RpmAccessBlockedException(_defaultDb->_d._root, _defaultDb->_d._dbPath));
00286     // tag handle invalid
00287     _defaultDb = 0;
00288     break;
00289   }
00290 
00291   return outstanding;
00292 }
00293 
00295 //
00296 //
00297 //      METHOD NAME : librpmDb::blockAccess
00298 //      METHOD TYPE : unsigned
00299 //
00300 unsigned librpmDb::blockAccess()
00301 {
00302   MIL << "Block access" << endl;
00303   _dbBlocked = true;
00304   return dbRelease( /*force*/true );
00305 }
00306 
00308 //
00309 //
00310 //      METHOD NAME : librpmDb::unblockAccess
00311 //      METHOD TYPE : void
00312 //
00313 void librpmDb::unblockAccess()
00314 {
00315   MIL << "Unblock access" << endl;
00316   _dbBlocked = false;
00317 }
00318 
00320 //
00321 //
00322 //      METHOD NAME : librpmDb::dumpState
00323 //      METHOD TYPE : ostream &
00324 //
00325 ostream & librpmDb::dumpState( ostream & str )
00326 {
00327   if ( !_defaultDb ) {
00328     return str << "[librpmDb " << (_dbBlocked?"BLOCKED":"CLOSED") << " " << stringPath( _defaultRoot, _defaultDbPath ) << "]";
00329   }
00330   return str << "[" << _defaultDb << "]";
00331 }
00332 
00334 //
00335 //      CLASS NAME : librpmDb (internal database handle interface (nonstatic))
00336 //
00338 
00340 //
00341 //
00342 //      METHOD NAME : librpmDb::librpmDb
00343 //      METHOD TYPE : Constructor
00344 //
00345 //      DESCRIPTION :
00346 //
00347 librpmDb::librpmDb( const Pathname & root_r, const Pathname & dbPath_r, bool readonly_r )
00348     : _d( * new D( root_r, dbPath_r, readonly_r ) )
00349 {
00350 }
00351 
00353 //
00354 //
00355 //      METHOD NAME : librpmDb::~librpmDb
00356 //      METHOD TYPE : Destructor
00357 //
00358 //      DESCRIPTION :
00359 //
00360 librpmDb::~librpmDb()
00361 {
00362   delete &_d;
00363 }
00364 
00366 //
00367 //
00368 //      METHOD NAME : librpmDb::unref_to
00369 //      METHOD TYPE : void
00370 //
00371 void librpmDb::unref_to( unsigned refCount_r ) const
00372 {
00373   if ( refCount_r == 1 ) {
00374     dbRelease();
00375   }
00376 }
00377 
00379 //
00380 //
00381 //      METHOD NAME : librpmDb::root
00382 //      METHOD TYPE : const Pathname &
00383 //
00384 const Pathname & librpmDb::root() const
00385 {
00386   return _d._root;
00387 }
00388 
00390 //
00391 //
00392 //      METHOD NAME : librpmDb::dbPath
00393 //      METHOD TYPE : const Pathname &
00394 //
00395 const Pathname & librpmDb::dbPath() const
00396 {
00397   return _d._dbPath;
00398 }
00399 
00401 //
00402 //
00403 //      METHOD NAME : librpmDb::error
00404 //      METHOD TYPE : PMError
00405 //
00406 shared_ptr<RpmException> librpmDb::error() const
00407 {
00408   return _d._error;
00409 }
00410 
00412 //
00413 //
00414 //      METHOD NAME : librpmDb::empty
00415 //      METHOD TYPE : bool
00416 //
00417 bool librpmDb::empty() const
00418 {
00419   return( valid() && ! *db_const_iterator( this ) );
00420 }
00421 
00423 //
00424 //
00425 //      METHOD NAME : librpmDb::size
00426 //      METHOD TYPE : unsigned
00427 //
00428 unsigned librpmDb::size() const
00429 {
00430   unsigned count = 0;
00431   if ( valid() )
00432     {
00433       dbiIndex dbi = dbiOpen( _d._db, RPMTAG_NAME, 0 );
00434       if ( dbi )
00435         {
00436           DBC * dbcursor = 0;
00437           dbiCopen( dbi, dbi->dbi_txnid, &dbcursor, 0 );
00438 
00439           DBT key, data;
00440           memset( &key, 0, sizeof(key) );
00441           memset( &data, 0, sizeof(data) );
00442           while ( dbiGet( dbi, dbcursor, &key, &data, DB_NEXT ) == 0 )
00443             count += data.size / dbi->dbi_jlen;
00444 
00445           dbiCclose( dbi, dbcursor, 0 );
00446           /* no need to close dbi */
00447         }
00448     }
00449   return count;
00450 }
00451 
00453 //
00454 //
00455 //      METHOD NAME : librpmDb::dont_call_it
00456 //      METHOD TYPE : void *
00457 //
00458 void * librpmDb::dont_call_it() const
00459 {
00460   return _d._db;
00461 }
00462 
00464 //
00465 //
00466 //      METHOD NAME : librpmDb::dumpOn
00467 //      METHOD TYPE : ostream &
00468 //
00469 //      DESCRIPTION :
00470 //
00471 ostream & librpmDb::dumpOn( ostream & str ) const
00472 {
00473   ReferenceCounted::dumpOn( str ) << _d;
00474   return str;
00475 }
00476 
00478 //
00479 //      CLASS NAME : librpmDb::DbDirInfo
00480 //
00482 
00484 //
00485 //
00486 //      METHOD NAME : librpmDb::DbDirInfo::DbDirInfo
00487 //      METHOD TYPE : Constructor
00488 //
00489 librpmDb::DbDirInfo::DbDirInfo( const Pathname & root_r, const Pathname & dbPath_r )
00490     : _root( root_r )
00491     , _dbPath( dbPath_r )
00492 {
00493   // check and adjust arguments
00494   if ( ! (root_r.absolute() && dbPath_r.absolute()) ) {
00495     ERR << "Relative path for root(" << _root << ") or dbPath(" << _dbPath << ")" << endl;
00496   } else {
00497     _dbDir   ( _root + _dbPath );
00498     _dbV4    ( _dbDir.path() + "Packages" );
00499     _dbV3    ( _dbDir.path() + "packages.rpm" );
00500     _dbV3ToV4( _dbDir.path() + "packages.rpm3" );
00501     DBG << *this << endl;
00502   }
00503 }
00504 
00506 //
00507 //
00508 //      METHOD NAME : librpmDb::DbDirInfo::update
00509 //      METHOD TYPE : void
00510 //
00511 void librpmDb::DbDirInfo::restat()
00512 {
00513   _dbDir();
00514   _dbV4();
00515   _dbV3();
00516   _dbV3ToV4();
00517   DBG << *this << endl;
00518 }
00519 
00520 /******************************************************************
00521 **
00522 **
00523 **      FUNCTION NAME : operator<<
00524 **      FUNCTION TYPE : std::ostream &
00525 */
00526 std::ostream & operator<<( std::ostream & str, const librpmDb::DbDirInfo & obj )
00527 {
00528   if ( obj.illegalArgs() ) {
00529     str << "ILLEGAL: '(" << obj.root() << ")" << obj.dbPath() << "'";
00530   } else {
00531     str << "'(" << obj.root() << ")" << obj.dbPath() << "':" << endl;
00532     str << "  Dir:    " << obj._dbDir << endl;
00533     str << "  V4:     " << obj._dbV4 << endl;
00534     str << "  V3:     " << obj._dbV3 << endl;
00535     str << "  V3ToV4: " << obj._dbV3ToV4;
00536   }
00537   return str;
00538 }
00539 
00541 //
00542 //      CLASS NAME : librpmDb::db_const_iterator::D
00546 class librpmDb::db_const_iterator::D {
00547   D & operator=( const D & ); // NO ASSIGNMENT!
00548   D ( const D & );            // NO COPY!
00549   public:
00550 
00551     librpmDb::constPtr     _dbptr;
00552     shared_ptr<RpmException> _dberr;
00553 
00554     RpmHeader::constPtr _hptr;
00555     rpmdbMatchIterator   _mi;
00556 
00557     D( librpmDb::constPtr dbptr_r )
00558       : _dbptr( dbptr_r )
00559       , _mi( 0 )
00560     {
00561       if ( !_dbptr ) {
00562         try {
00563           librpmDb::dbAccess( _dbptr );
00564         }
00565         catch (const RpmException & excpt_r)
00566         {
00567           ZYPP_CAUGHT(excpt_r);
00568         }
00569         if ( !_dbptr ) {
00570           WAR << "No database access: " << _dberr << endl;
00571         }
00572       } else {
00573         destroy(); // Checks whether _dbptr still valid
00574       }
00575     }
00576 
00577     ~D() {
00578       if ( _mi ) {
00579         ::rpmdbFreeIterator( _mi );
00580       }
00581     }
00582 
00587     bool create( int rpmtag, const void * keyp = NULL, size_t keylen = 0 ) {
00588       destroy();
00589       if ( ! _dbptr )
00590         return false;
00591       _mi = ::rpmdbInitIterator( _dbptr->_d._db, rpmTag(rpmtag), keyp, keylen );
00592       return _mi;
00593     }
00594 
00599     bool destroy() {
00600       if ( _mi ) {
00601         _mi = ::rpmdbFreeIterator( _mi );
00602         _hptr = 0;
00603       }
00604       if ( _dbptr && _dbptr->error() ) {
00605         _dberr = _dbptr->error();
00606         WAR << "Lost database access: " << _dberr << endl;
00607         _dbptr = 0;
00608       }
00609       return false;
00610     }
00611 
00616     bool advance() {
00617       if ( !_mi )
00618         return false;
00619       Header h = ::rpmdbNextIterator( _mi );
00620       if ( ! h ) {
00621         destroy();
00622         return false;
00623       }
00624       _hptr = new RpmHeader( h );
00625       return true;
00626     }
00627 
00631     bool init( int rpmtag, const void * keyp = NULL, size_t keylen = 0 ) {
00632       if ( ! create( rpmtag, keyp, keylen ) )
00633         return false;
00634       return advance();
00635     }
00636 
00641     bool set( int off_r ) {
00642       if ( ! create( RPMDBI_PACKAGES ) )
00643         return false;
00644 #warning TESTCASE: rpmdbAppendIterator and (non)sequential access?
00645       ::rpmdbAppendIterator( _mi, &off_r, 1 );
00646       return advance();
00647     }
00648 
00649     unsigned offset() {
00650       return( _mi ? ::rpmdbGetIteratorOffset( _mi ) : 0 );
00651     }
00652 
00653     int size() {
00654       if ( !_mi )
00655         return 0;
00656       int ret = ::rpmdbGetIteratorCount( _mi );
00657 #warning TESTCASE: rpmdbGetIteratorCount returns 0 on sequential access?
00658       return( ret ? ret : -1 ); // -1: sequential access
00659     }
00660 };
00661 
00663 
00665 //
00666 //      CLASS NAME : librpmDb::Ptr::db_const_iterator
00667 //
00669 
00671 //
00672 //
00673 //      METHOD NAME : librpmDb::db_const_iterator::db_iterator
00674 //      METHOD TYPE : Constructor
00675 //
00676 librpmDb::db_const_iterator::db_const_iterator( librpmDb::constPtr dbptr_r )
00677     : _d( * new D( dbptr_r ) )
00678 {
00679   findAll();
00680 }
00681 
00683 //
00684 //
00685 //      METHOD NAME : librpmDb::db_const_iterator::~db_const_iterator
00686 //      METHOD TYPE : Destructor
00687 //
00688 librpmDb::db_const_iterator::~db_const_iterator()
00689 {
00690   delete &_d;
00691 }
00692 
00694 //
00695 //
00696 //      METHOD NAME : librpmDb::db_const_iterator::operator++
00697 //      METHOD TYPE : void
00698 //
00699 void librpmDb::db_const_iterator::operator++()
00700 {
00701   _d.advance();
00702 }
00703 
00705 //
00706 //
00707 //      METHOD NAME : librpmDb::db_const_iterator::dbHdrNum
00708 //      METHOD TYPE : unsigned
00709 //
00710 unsigned librpmDb::db_const_iterator::dbHdrNum() const
00711 {
00712   return _d.offset();
00713 }
00714 
00716 //
00717 //
00718 //      METHOD NAME : librpmDb::db_const_iterator::operator*
00719 //      METHOD TYPE : const RpmHeader::constPtr &
00720 //
00721 const RpmHeader::constPtr & librpmDb::db_const_iterator::operator*() const
00722 {
00723   return _d._hptr;
00724 }
00725 
00727 //
00728 //
00729 //      METHOD NAME : librpmDb::db_const_iterator::dbError
00730 //      METHOD TYPE : PMError
00731 //
00732 shared_ptr<RpmException> librpmDb::db_const_iterator::dbError() const
00733 {
00734   if ( _d._dbptr )
00735     return _d._dbptr->error();
00736 
00737   return _d._dberr;
00738 }
00739 
00740 /******************************************************************
00741 **
00742 **
00743 **      FUNCTION NAME : operator<<
00744 **      FUNCTION TYPE : ostream &
00745 */
00746 ostream & operator<<( ostream & str, const librpmDb::db_const_iterator & obj )
00747 {
00748   str << "db_const_iterator(" << obj._d._dbptr
00749     << " Size:" << obj._d.size()
00750       << " HdrNum:" << obj._d.offset()
00751         << ")";
00752   return str;
00753 }
00754 
00756 //
00757 //
00758 //      METHOD NAME : librpmDb::db_const_iterator::findAll
00759 //      METHOD TYPE : bool
00760 //
00761 bool librpmDb::db_const_iterator::findAll()
00762 {
00763   return _d.init( RPMDBI_PACKAGES );
00764 }
00765 
00767 //
00768 //
00769 //      METHOD NAME : librpmDb::db_const_iterator::findByFile
00770 //      METHOD TYPE : bool
00771 //
00772 bool librpmDb::db_const_iterator::findByFile( const std::string & file_r )
00773 {
00774   return _d.init( RPMTAG_BASENAMES, file_r.c_str() );
00775 }
00776 
00778 //
00779 //
00780 //      METHOD NAME : librpmDb::db_const_iterator::findByProvides
00781 //      METHOD TYPE : bool
00782 //
00783 bool librpmDb::db_const_iterator::findByProvides( const std::string & tag_r )
00784 {
00785   return _d.init( RPMTAG_PROVIDENAME, tag_r.c_str() );
00786 }
00787 
00789 //
00790 //
00791 //      METHOD NAME : librpmDb::db_const_iterator::findByRequiredBy
00792 //      METHOD TYPE : bool
00793 //
00794 bool librpmDb::db_const_iterator::findByRequiredBy( const std::string & tag_r )
00795 {
00796   return _d.init( RPMTAG_REQUIRENAME, tag_r.c_str() );
00797 }
00798 
00800 //
00801 //
00802 //      METHOD NAME : librpmDb::db_const_iterator::findByConflicts
00803 //      METHOD TYPE : bool
00804 //
00805 bool librpmDb::db_const_iterator::findByConflicts( const std::string & tag_r )
00806 {
00807   return _d.init( RPMTAG_CONFLICTNAME, tag_r.c_str() );
00808 }
00809 
00811 //
00812 //
00813 //      METHOD NAME : librpmDb::findByName
00814 //      METHOD TYPE : bool
00815 //
00816 bool librpmDb::db_const_iterator::findByName( const string & name_r )
00817 {
00818   return _d.init( RPMTAG_NAME, name_r.c_str() );
00819 }
00820 
00822 //
00823 //
00824 //      METHOD NAME : librpmDb::db_const_iterator::findPackage
00825 //      METHOD TYPE : bool
00826 //
00827 bool librpmDb::db_const_iterator::findPackage( const string & name_r )
00828 {
00829   if ( ! _d.init( RPMTAG_NAME, name_r.c_str() ) )
00830     return false;
00831 
00832   if ( _d.size() == 1 )
00833     return true;
00834 
00835   // check installtime on multiple entries
00836   int match    = 0;
00837   time_t itime = 0;
00838   for ( ; operator*(); operator++() ) {
00839     if ( operator*()->tag_installtime() > itime ) {
00840       match = _d.offset();
00841       itime = operator*()->tag_installtime();
00842     }
00843   }
00844 
00845   return _d.set( match );
00846 }
00847 
00849 //
00850 //
00851 //      METHOD NAME : librpmDb::db_const_iterator::findPackage
00852 //      METHOD TYPE : bool
00853 //
00854 bool librpmDb::db_const_iterator::findPackage( const std::string & name_r, const Edition & ed_r )
00855 {
00856   if ( ! _d.init( RPMTAG_NAME, name_r.c_str() ) )
00857     return false;
00858 
00859   for ( ; operator*(); operator++() ) {
00860     if ( ed_r == operator*()->tag_edition() ) {
00861       int match = _d.offset();
00862       return _d.set( match );
00863     }
00864   }
00865 
00866   return _d.destroy();
00867 }
00868 
00870 //
00871 //
00872 //      METHOD NAME : librpmDb::db_const_iterator::findPackage
00873 //      METHOD TYPE : bool
00874 //
00875 bool librpmDb::db_const_iterator::findPackage( const Package::constPtr & which_r )
00876 {
00877   if ( ! which_r )
00878     return _d.destroy();
00879 
00880   return findPackage( which_r->name(), which_r->edition() );
00881 }
00882 
00883     } // namespace rpm
00884   } // namespace target
00885 } // namespace zypp

Generated on Tue Nov 28 16:49:33 2006 for zypp by  doxygen 1.5.0