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   rpmdb          _db;     // database handle
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       , _db    ( 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     // check whether to create a new db
00064     PathInfo master( _root + _dbPath + "Packages" );
00065     if ( ! master.isFile() )
00066     {
00067       // init database
00068       int res = ::rpmdbInit( root, perms );
00069       if ( res )
00070       {
00071         ERR << "rpmdbInit error(" << res << "): " << *this << endl;
00072         _error = shared_ptr<RpmInitException>(new RpmInitException(_root, _dbPath));
00073         ZYPP_THROW(*_error);
00074       }
00075     }
00076 
00077     // open database
00078     int res = ::rpmdbOpen( root, &_db, (readonly_r ? O_RDONLY : O_RDWR ), perms );
00079     if ( res || !_db )
00080     {
00081       if ( _db )
00082       {
00083         ::rpmdbClose( _db );
00084         _db = 0;
00085       }
00086       ERR << "rpmdbOpen error(" << res << "): " << *this << endl;
00087       _error = shared_ptr<RpmDbOpenException>(new RpmDbOpenException(_root, _dbPath));
00088       ZYPP_THROW(*_error);
00089       return;
00090     }
00091 
00092     DBG << "DBACCESS " << *this << endl;
00093   }
00094 
00095   ~D()
00096   {
00097     if ( _db )
00098     {
00099       ::rpmdbClose( _db );
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 #if defined(_RPM_4_4_COMPAT) || defined(_RPM_5)
00456     // looks like rpm-4.7 has no public dbi interface anymore
00457     int dbi = ::rpmdbOpen("/", &_d._db, O_RDONLY, 0);
00458     if (dbi == 0) {
00459         rpmdbMatchIterator mi = ::rpmdbInitIterator(_d._db, RPMTAG_NAME, NULL, 0);
00460         if (mi != NULL) {
00461             for (;;) {
00462                 Header rpmHeader = ::rpmdbNextIterator(mi);
00463                 if (rpmHeader != NULL)
00464                     ++count;
00465             }
00466         }
00467         ::rpmdbClose(_d._db);
00468     }
00469 #else
00470     dbiIndex dbi = dbiOpen( _d._db, RPMTAG_NAME, 0 );
00471     if ( dbi )
00472     {
00473       DBC * dbcursor = 0;
00474       dbiCopen( dbi, dbi->dbi_txnid, &dbcursor, 0 );
00475 
00476       DBT key, data;
00477       memset( &key, 0, sizeof(key) );
00478       memset( &data, 0, sizeof(data) );
00479       while ( dbiGet( dbi, dbcursor, &key, &data, DB_NEXT ) == 0 )
00480         count += data.size / dbi->dbi_jlen;
00481 
00482       dbiCclose( dbi, dbcursor, 0 );
00483       /* no need to close dbi */
00484     }
00485 #endif
00486   }
00487   return count;
00488 }
00489 
00491 //
00492 //
00493 //      METHOD NAME : librpmDb::dont_call_it
00494 //      METHOD TYPE : void *
00495 //
00496 void * librpmDb::dont_call_it() const
00497 {
00498   return _d._db;
00499 }
00500 
00502 //
00503 //
00504 //      METHOD NAME : librpmDb::dumpOn
00505 //      METHOD TYPE : ostream &
00506 //
00507 //      DESCRIPTION :
00508 //
00509 ostream & librpmDb::dumpOn( ostream & str ) const
00510 {
00511   ReferenceCounted::dumpOn( str ) << _d;
00512   return str;
00513 }
00514 
00516 //
00517 //      CLASS NAME : librpmDb::DbDirInfo
00518 //
00520 
00522 //
00523 //
00524 //      METHOD NAME : librpmDb::DbDirInfo::DbDirInfo
00525 //      METHOD TYPE : Constructor
00526 //
00527 librpmDb::DbDirInfo::DbDirInfo( const Pathname & root_r, const Pathname & dbPath_r )
00528     : _root( root_r )
00529     , _dbPath( dbPath_r )
00530 {
00531   // check and adjust arguments
00532   if ( ! (root_r.absolute() && dbPath_r.absolute()) )
00533   {
00534     ERR << "Relative path for root(" << _root << ") or dbPath(" << _dbPath << ")" << endl;
00535   }
00536   else
00537   {
00538     _dbDir   ( _root + _dbPath );
00539     _dbV4    ( _dbDir.path() + "Packages" );
00540     _dbV3    ( _dbDir.path() + "packages.rpm" );
00541     _dbV3ToV4( _dbDir.path() + "packages.rpm3" );
00542     DBG << *this << endl;
00543   }
00544 }
00545 
00547 //
00548 //
00549 //      METHOD NAME : librpmDb::DbDirInfo::update
00550 //      METHOD TYPE : void
00551 //
00552 void librpmDb::DbDirInfo::restat()
00553 {
00554   _dbDir();
00555   _dbV4();
00556   _dbV3();
00557   _dbV3ToV4();
00558   DBG << *this << endl;
00559 }
00560 
00561 /******************************************************************
00562 **
00563 **
00564 **      FUNCTION NAME : operator<<
00565 **      FUNCTION TYPE : std::ostream &
00566 */
00567 std::ostream & operator<<( std::ostream & str, const librpmDb::DbDirInfo & obj )
00568 {
00569   if ( obj.illegalArgs() )
00570   {
00571     str << "ILLEGAL: '(" << obj.root() << ")" << obj.dbPath() << "'";
00572   }
00573   else
00574   {
00575     str << "'(" << obj.root() << ")" << obj.dbPath() << "':" << endl;
00576     str << "  Dir:    " << obj._dbDir << endl;
00577     str << "  V4:     " << obj._dbV4 << endl;
00578     str << "  V3:     " << obj._dbV3 << endl;
00579     str << "  V3ToV4: " << obj._dbV3ToV4;
00580   }
00581   return str;
00582 }
00583 
00585 //
00586 //      CLASS NAME : librpmDb::db_const_iterator::D
00590 class librpmDb::db_const_iterator::D
00591 {
00592   D & operator=( const D & ); // NO ASSIGNMENT!
00593   D ( const D & );            // NO COPY!
00594 public:
00595 
00596   librpmDb::constPtr     _dbptr;
00597   shared_ptr<RpmException> _dberr;
00598 
00599   RpmHeader::constPtr _hptr;
00600   rpmdbMatchIterator   _mi;
00601 
00602   D( librpmDb::constPtr dbptr_r )
00603       : _dbptr( dbptr_r )
00604       , _mi( 0 )
00605   {
00606     if ( !_dbptr )
00607     {
00608       try
00609       {
00610         librpmDb::dbAccess( _dbptr );
00611       }
00612       catch (const RpmException & excpt_r)
00613       {
00614         ZYPP_CAUGHT(excpt_r);
00615       }
00616       if ( !_dbptr )
00617       {
00618         WAR << "No database access: " << _dberr << endl;
00619       }
00620     }
00621     else
00622     {
00623       destroy(); // Checks whether _dbptr still valid
00624     }
00625   }
00626 
00627   ~D()
00628   {
00629     if ( _mi )
00630     {
00631       ::rpmdbFreeIterator( _mi );
00632     }
00633   }
00634 
00639   bool create( int rpmtag, const void * keyp = NULL, size_t keylen = 0 )
00640   {
00641     destroy();
00642     if ( ! _dbptr )
00643       return false;
00644     _mi = ::rpmdbInitIterator( _dbptr->_d._db, rpmTag(rpmtag), keyp, keylen );
00645     return _mi;
00646   }
00647 
00652   bool destroy()
00653   {
00654     if ( _mi )
00655     {
00656       _mi = ::rpmdbFreeIterator( _mi );
00657       _hptr = 0;
00658     }
00659     if ( _dbptr && _dbptr->error() )
00660     {
00661       _dberr = _dbptr->error();
00662       WAR << "Lost database access: " << _dberr << endl;
00663       _dbptr = 0;
00664     }
00665     return false;
00666   }
00667 
00672   bool advance()
00673   {
00674     if ( !_mi )
00675       return false;
00676     Header h = ::rpmdbNextIterator( _mi );
00677     if ( ! h )
00678     {
00679       destroy();
00680       return false;
00681     }
00682     _hptr = new RpmHeader( h );
00683     return true;
00684   }
00685 
00689   bool init( int rpmtag, const void * keyp = NULL, size_t keylen = 0 )
00690   {
00691     if ( ! create( rpmtag, keyp, keylen ) )
00692       return false;
00693     return advance();
00694   }
00695 
00700   bool set( int off_r )
00701   {
00702     if ( ! create( RPMDBI_PACKAGES ) )
00703       return false;
00704 #warning TESTCASE: rpmdbAppendIterator and (non)sequential access?
00705     ::rpmdbAppendIterator( _mi, &off_r, 1 );
00706     return advance();
00707   }
00708 
00709   unsigned offset()
00710   {
00711     return( _mi ? ::rpmdbGetIteratorOffset( _mi ) : 0 );
00712   }
00713 
00714   int size()
00715   {
00716     if ( !_mi )
00717       return 0;
00718     int ret = ::rpmdbGetIteratorCount( _mi );
00719 #warning TESTCASE: rpmdbGetIteratorCount returns 0 on sequential access?
00720     return( ret ? ret : -1 ); // -1: sequential access
00721   }
00722 };
00723 
00725 
00727 //
00728 //      CLASS NAME : librpmDb::Ptr::db_const_iterator
00729 //
00731 
00733 //
00734 //
00735 //      METHOD NAME : librpmDb::db_const_iterator::db_iterator
00736 //      METHOD TYPE : Constructor
00737 //
00738 librpmDb::db_const_iterator::db_const_iterator( librpmDb::constPtr dbptr_r )
00739     : _d( * new D( dbptr_r ) )
00740 {
00741   findAll();
00742 }
00743 
00745 //
00746 //
00747 //      METHOD NAME : librpmDb::db_const_iterator::~db_const_iterator
00748 //      METHOD TYPE : Destructor
00749 //
00750 librpmDb::db_const_iterator::~db_const_iterator()
00751 {
00752   delete &_d;
00753 }
00754 
00756 //
00757 //
00758 //      METHOD NAME : librpmDb::db_const_iterator::operator++
00759 //      METHOD TYPE : void
00760 //
00761 void librpmDb::db_const_iterator::operator++()
00762 {
00763   _d.advance();
00764 }
00765 
00767 //
00768 //
00769 //      METHOD NAME : librpmDb::db_const_iterator::dbHdrNum
00770 //      METHOD TYPE : unsigned
00771 //
00772 unsigned librpmDb::db_const_iterator::dbHdrNum() const
00773 {
00774   return _d.offset();
00775 }
00776 
00778 //
00779 //
00780 //      METHOD NAME : librpmDb::db_const_iterator::operator*
00781 //      METHOD TYPE : const RpmHeader::constPtr &
00782 //
00783 const RpmHeader::constPtr & librpmDb::db_const_iterator::operator*() const
00784 {
00785   return _d._hptr;
00786 }
00787 
00789 //
00790 //
00791 //      METHOD NAME : librpmDb::db_const_iterator::dbError
00792 //      METHOD TYPE : PMError
00793 //
00794 shared_ptr<RpmException> librpmDb::db_const_iterator::dbError() const
00795 {
00796   if ( _d._dbptr )
00797     return _d._dbptr->error();
00798 
00799   return _d._dberr;
00800 }
00801 
00802 /******************************************************************
00803 **
00804 **
00805 **      FUNCTION NAME : operator<<
00806 **      FUNCTION TYPE : ostream &
00807 */
00808 ostream & operator<<( ostream & str, const librpmDb::db_const_iterator & obj )
00809 {
00810   str << "db_const_iterator(" << obj._d._dbptr
00811   << " Size:" << obj._d.size()
00812   << " HdrNum:" << obj._d.offset()
00813   << ")";
00814   return str;
00815 }
00816 
00818 //
00819 //
00820 //      METHOD NAME : librpmDb::db_const_iterator::findAll
00821 //      METHOD TYPE : bool
00822 //
00823 bool librpmDb::db_const_iterator::findAll()
00824 {
00825   return _d.init( RPMDBI_PACKAGES );
00826 }
00827 
00829 //
00830 //
00831 //      METHOD NAME : librpmDb::db_const_iterator::findByFile
00832 //      METHOD TYPE : bool
00833 //
00834 bool librpmDb::db_const_iterator::findByFile( const std::string & file_r )
00835 {
00836   return _d.init( RPMTAG_BASENAMES, file_r.c_str() );
00837 }
00838 
00840 //
00841 //
00842 //      METHOD NAME : librpmDb::db_const_iterator::findByProvides
00843 //      METHOD TYPE : bool
00844 //
00845 bool librpmDb::db_const_iterator::findByProvides( const std::string & tag_r )
00846 {
00847   return _d.init( RPMTAG_PROVIDENAME, tag_r.c_str() );
00848 }
00849 
00851 //
00852 //
00853 //      METHOD NAME : librpmDb::db_const_iterator::findByRequiredBy
00854 //      METHOD TYPE : bool
00855 //
00856 bool librpmDb::db_const_iterator::findByRequiredBy( const std::string & tag_r )
00857 {
00858   return _d.init( RPMTAG_REQUIRENAME, tag_r.c_str() );
00859 }
00860 
00862 //
00863 //
00864 //      METHOD NAME : librpmDb::db_const_iterator::findByConflicts
00865 //      METHOD TYPE : bool
00866 //
00867 bool librpmDb::db_const_iterator::findByConflicts( const std::string & tag_r )
00868 {
00869   return _d.init( RPMTAG_CONFLICTNAME, tag_r.c_str() );
00870 }
00871 
00873 //
00874 //
00875 //      METHOD NAME : librpmDb::findByName
00876 //      METHOD TYPE : bool
00877 //
00878 bool librpmDb::db_const_iterator::findByName( const string & name_r )
00879 {
00880   return _d.init( RPMTAG_NAME, name_r.c_str() );
00881 }
00882 
00884 //
00885 //
00886 //      METHOD NAME : librpmDb::db_const_iterator::findPackage
00887 //      METHOD TYPE : bool
00888 //
00889 bool librpmDb::db_const_iterator::findPackage( const string & name_r )
00890 {
00891   if ( ! _d.init( RPMTAG_NAME, name_r.c_str() ) )
00892     return false;
00893 
00894   if ( _d.size() == 1 )
00895     return true;
00896 
00897   // check installtime on multiple entries
00898   int match    = 0;
00899   time_t itime = 0;
00900   for ( ; operator*(); operator++() )
00901   {
00902     if ( operator*()->tag_installtime() > itime )
00903     {
00904       match = _d.offset();
00905       itime = operator*()->tag_installtime();
00906     }
00907   }
00908 
00909   return _d.set( match );
00910 }
00911 
00913 //
00914 //
00915 //      METHOD NAME : librpmDb::db_const_iterator::findPackage
00916 //      METHOD TYPE : bool
00917 //
00918 bool librpmDb::db_const_iterator::findPackage( const std::string & name_r, const Edition & ed_r )
00919 {
00920   if ( ! _d.init( RPMTAG_NAME, name_r.c_str() ) )
00921     return false;
00922 
00923   for ( ; operator*(); operator++() )
00924   {
00925     if ( ed_r == operator*()->tag_edition() )
00926     {
00927       int match = _d.offset();
00928       return _d.set( match );
00929     }
00930   }
00931 
00932   return _d.destroy();
00933 }
00934 
00936 //
00937 //
00938 //      METHOD NAME : librpmDb::db_const_iterator::findPackage
00939 //      METHOD TYPE : bool
00940 //
00941 bool librpmDb::db_const_iterator::findPackage( const Package::constPtr & which_r )
00942 {
00943   if ( ! which_r )
00944     return _d.destroy();
00945 
00946   return findPackage( which_r->name(), which_r->edition() );
00947 }
00948 
00949 } // namespace rpm
00950 } // namespace target
00951 } // namespace zypp

doxygen