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