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   // should speed up convertdb and rebuilddb.
00138   ::addMacro( NULL, "_rpmdb_rebuild", NULL, "%{nil}", RMIL_CMDLINE );
00139 
00140   initialized = true; // Necessary to be able to use exand().
00141 
00142 #define OUTVAL(n) << " (" #n ":" << expand( "%{" #n "}" ) << ")"
00143   MIL << "librpm init done:"
00144   OUTVAL(_target)
00145   OUTVAL(_dbpath)
00146   << endl;
00147 #undef OUTVAL
00148   return initialized;
00149 }
00150 
00152 //
00153 //
00154 //      METHOD NAME : librpmDb::expand
00155 //      METHOD TYPE : std::string
00156 //
00157 std::string librpmDb::expand( const std::string & macro_r )
00158 {
00159   if ( ! globalInit() )
00160     return macro_r;  // unexpanded
00161 
00162   char * val = ::rpmExpand( macro_r.c_str(), NULL );
00163   if ( !val )
00164     return "";
00165 
00166   string ret( val );
00167   free( val );
00168   return ret;
00169 }
00170 
00172 //
00173 //
00174 //      METHOD NAME : librpmDb::newLibrpmDb
00175 //      METHOD TYPE : librpmDb *
00176 //
00177 librpmDb * librpmDb::newLibrpmDb( Pathname root_r, Pathname dbPath_r, bool readonly_r )
00178 {
00179   // check arguments
00180   if ( ! (root_r.absolute() && dbPath_r.absolute()) )
00181   {
00182     ZYPP_THROW(RpmInvalidRootException(root_r, dbPath_r));
00183   }
00184 
00185   // initialize librpm
00186   if ( ! globalInit() )
00187   {
00188     ZYPP_THROW(GlobalRpmInitException());
00189   }
00190 
00191   // open rpmdb
00192   librpmDb * ret = 0;
00193   try
00194   {
00195     ret = new librpmDb( root_r, dbPath_r, readonly_r );
00196   }
00197   catch (const RpmException & excpt_r)
00198   {
00199     ZYPP_CAUGHT(excpt_r);
00200     delete ret;
00201     ret = 0;
00202     ZYPP_RETHROW(excpt_r);
00203   }
00204   return ret;
00205 }
00206 
00208 //
00209 //
00210 //      METHOD NAME : librpmDb::dbAccess
00211 //      METHOD TYPE : PMError
00212 //
00213 void librpmDb::dbAccess( const Pathname & root_r, const Pathname & dbPath_r )
00214 {
00215   // check arguments
00216   if ( ! (root_r.absolute() && dbPath_r.absolute()) )
00217   {
00218     ZYPP_THROW(RpmInvalidRootException(root_r, dbPath_r));
00219   }
00220 
00221   if ( _defaultDb )
00222   {
00223     // already accessing a database: switching is not allowed.
00224     if ( _defaultRoot == root_r && _defaultDbPath == dbPath_r )
00225       return;
00226     else
00227     {
00228       ZYPP_THROW(RpmDbAlreadyOpenException(_defaultRoot, _defaultDbPath, root_r, dbPath_r));
00229     }
00230   }
00231 
00232   // got no database: we could switch to a new one (even if blocked!)
00233   _defaultRoot = root_r;
00234   _defaultDbPath = dbPath_r;
00235   MIL << "Set new database location: " << stringPath( _defaultRoot, _defaultDbPath ) << endl;
00236 
00237   return dbAccess();
00238 }
00239 
00241 //
00242 //
00243 //      METHOD NAME : librpmDb::dbAccess
00244 //      METHOD TYPE : PMError
00245 //
00246 void librpmDb::dbAccess()
00247 {
00248   if ( _dbBlocked )
00249   {
00250     ZYPP_THROW(RpmAccessBlockedException(_defaultRoot, _defaultDbPath));
00251   }
00252 
00253   if ( !_defaultDb )
00254   {
00255     // get access
00256     _defaultDb = newLibrpmDb( _defaultRoot, _defaultDbPath, /*readonly*/true );
00257   }
00258 }
00259 
00261 //
00262 //
00263 //      METHOD NAME : librpmDb::dbAccess
00264 //      METHOD TYPE : PMError
00265 //
00266 void librpmDb::dbAccess( librpmDb::constPtr & ptr_r )
00267 {
00268   try
00269   {
00270     dbAccess();
00271   }
00272   catch (const RpmException & excpt_r)
00273   {
00274     ZYPP_CAUGHT(excpt_r);
00275     ptr_r = 0;
00276     ZYPP_RETHROW(excpt_r);
00277   }
00278   ptr_r = _defaultDb;
00279 }
00280 
00282 //
00283 //
00284 //      METHOD NAME : librpmDb::dbRelease
00285 //      METHOD TYPE : unsigned
00286 //
00287 unsigned librpmDb::dbRelease( bool force_r )
00288 {
00289   if ( !_defaultDb )
00290   {
00291     return 0;
00292   }
00293 
00294   unsigned outstanding = _defaultDb->refCount() - 1; // refCount can't be 0
00295 
00296   switch ( outstanding )
00297   {
00298   default:
00299     if ( !force_r )
00300     {
00301       DBG << "dbRelease: keep access, outstanding " << outstanding << endl;
00302       break;
00303     }
00304     // else fall through:
00305   case 0:
00306     DBG << "dbRelease: release" << (force_r && outstanding ? "(forced)" : "")
00307     << ", outstanding " << outstanding << endl;
00308 
00309     _defaultDb->_d._error = shared_ptr<RpmAccessBlockedException>(new RpmAccessBlockedException(_defaultDb->_d._root, _defaultDb->_d._dbPath));
00310     // tag handle invalid
00311     _defaultDb = 0;
00312     break;
00313   }
00314 
00315   return outstanding;
00316 }
00317 
00319 //
00320 //
00321 //      METHOD NAME : librpmDb::blockAccess
00322 //      METHOD TYPE : unsigned
00323 //
00324 unsigned librpmDb::blockAccess()
00325 {
00326   MIL << "Block access" << endl;
00327   _dbBlocked = true;
00328   return dbRelease( /*force*/true );
00329 }
00330 
00332 //
00333 //
00334 //      METHOD NAME : librpmDb::unblockAccess
00335 //      METHOD TYPE : void
00336 //
00337 void librpmDb::unblockAccess()
00338 {
00339   MIL << "Unblock access" << endl;
00340   _dbBlocked = false;
00341 }
00342 
00344 //
00345 //
00346 //      METHOD NAME : librpmDb::dumpState
00347 //      METHOD TYPE : ostream &
00348 //
00349 ostream & librpmDb::dumpState( ostream & str )
00350 {
00351   if ( !_defaultDb )
00352   {
00353     return str << "[librpmDb " << (_dbBlocked?"BLOCKED":"CLOSED") << " " << stringPath( _defaultRoot, _defaultDbPath ) << "]";
00354   }
00355   return str << "[" << _defaultDb << "]";
00356 }
00357 
00359 //
00360 //      CLASS NAME : librpmDb (internal database handle interface (nonstatic))
00361 //
00363 
00365 //
00366 //
00367 //      METHOD NAME : librpmDb::librpmDb
00368 //      METHOD TYPE : Constructor
00369 //
00370 //      DESCRIPTION :
00371 //
00372 librpmDb::librpmDb( const Pathname & root_r, const Pathname & dbPath_r, bool readonly_r )
00373     : _d( * new D( root_r, dbPath_r, readonly_r ) )
00374 {}
00375 
00377 //
00378 //
00379 //      METHOD NAME : librpmDb::~librpmDb
00380 //      METHOD TYPE : Destructor
00381 //
00382 //      DESCRIPTION :
00383 //
00384 librpmDb::~librpmDb()
00385 {
00386   delete &_d;
00387 }
00388 
00390 //
00391 //
00392 //      METHOD NAME : librpmDb::unref_to
00393 //      METHOD TYPE : void
00394 //
00395 void librpmDb::unref_to( unsigned refCount_r ) const
00396 {
00397   if ( refCount_r == 1 )
00398   {
00399     dbRelease();
00400   }
00401 }
00402 
00404 //
00405 //
00406 //      METHOD NAME : librpmDb::root
00407 //      METHOD TYPE : const Pathname &
00408 //
00409 const Pathname & librpmDb::root() const
00410 {
00411   return _d._root;
00412 }
00413 
00415 //
00416 //
00417 //      METHOD NAME : librpmDb::dbPath
00418 //      METHOD TYPE : const Pathname &
00419 //
00420 const Pathname & librpmDb::dbPath() const
00421 {
00422   return _d._dbPath;
00423 }
00424 
00426 //
00427 //
00428 //      METHOD NAME : librpmDb::error
00429 //      METHOD TYPE : PMError
00430 //
00431 shared_ptr<RpmException> librpmDb::error() const
00432 {
00433   return _d._error;
00434 }
00435 
00437 //
00438 //
00439 //      METHOD NAME : librpmDb::empty
00440 //      METHOD TYPE : bool
00441 //
00442 bool librpmDb::empty() const
00443 {
00444   return( valid() && ! *db_const_iterator( this ) );
00445 }
00446 
00448 //
00449 //
00450 //      METHOD NAME : librpmDb::size
00451 //      METHOD TYPE : unsigned
00452 //
00453 unsigned librpmDb::size() const
00454 {
00455   unsigned count = 0;
00456   if ( valid() )
00457   {
00458     dbiIndex dbi = dbiOpen( _d._db, RPMTAG_NAME, 0 );
00459     if ( dbi )
00460     {
00461       DBC * dbcursor = 0;
00462       dbiCopen( dbi, dbi->dbi_txnid, &dbcursor, 0 );
00463 
00464       DBT key, data;
00465       memset( &key, 0, sizeof(key) );
00466       memset( &data, 0, sizeof(data) );
00467       while ( dbiGet( dbi, dbcursor, &key, &data, DB_NEXT ) == 0 )
00468         count += data.size / dbi->dbi_jlen;
00469 
00470       dbiCclose( dbi, dbcursor, 0 );
00471       /* no need to close dbi */
00472     }
00473   }
00474   return count;
00475 }
00476 
00478 //
00479 //
00480 //      METHOD NAME : librpmDb::dont_call_it
00481 //      METHOD TYPE : void *
00482 //
00483 void * librpmDb::dont_call_it() const
00484 {
00485   return _d._db;
00486 }
00487 
00489 //
00490 //
00491 //      METHOD NAME : librpmDb::dumpOn
00492 //      METHOD TYPE : ostream &
00493 //
00494 //      DESCRIPTION :
00495 //
00496 ostream & librpmDb::dumpOn( ostream & str ) const
00497 {
00498   ReferenceCounted::dumpOn( str ) << _d;
00499   return str;
00500 }
00501 
00503 //
00504 //      CLASS NAME : librpmDb::DbDirInfo
00505 //
00507 
00509 //
00510 //
00511 //      METHOD NAME : librpmDb::DbDirInfo::DbDirInfo
00512 //      METHOD TYPE : Constructor
00513 //
00514 librpmDb::DbDirInfo::DbDirInfo( const Pathname & root_r, const Pathname & dbPath_r )
00515     : _root( root_r )
00516     , _dbPath( dbPath_r )
00517 {
00518   // check and adjust arguments
00519   if ( ! (root_r.absolute() && dbPath_r.absolute()) )
00520   {
00521     ERR << "Relative path for root(" << _root << ") or dbPath(" << _dbPath << ")" << endl;
00522   }
00523   else
00524   {
00525     _dbDir   ( _root + _dbPath );
00526     _dbV4    ( _dbDir.path() + "Packages" );
00527     _dbV3    ( _dbDir.path() + "packages.rpm" );
00528     _dbV3ToV4( _dbDir.path() + "packages.rpm3" );
00529     DBG << *this << endl;
00530   }
00531 }
00532 
00534 //
00535 //
00536 //      METHOD NAME : librpmDb::DbDirInfo::update
00537 //      METHOD TYPE : void
00538 //
00539 void librpmDb::DbDirInfo::restat()
00540 {
00541   _dbDir();
00542   _dbV4();
00543   _dbV3();
00544   _dbV3ToV4();
00545   DBG << *this << endl;
00546 }
00547 
00548 /******************************************************************
00549 **
00550 **
00551 **      FUNCTION NAME : operator<<
00552 **      FUNCTION TYPE : std::ostream &
00553 */
00554 std::ostream & operator<<( std::ostream & str, const librpmDb::DbDirInfo & obj )
00555 {
00556   if ( obj.illegalArgs() )
00557   {
00558     str << "ILLEGAL: '(" << obj.root() << ")" << obj.dbPath() << "'";
00559   }
00560   else
00561   {
00562     str << "'(" << obj.root() << ")" << obj.dbPath() << "':" << endl;
00563     str << "  Dir:    " << obj._dbDir << endl;
00564     str << "  V4:     " << obj._dbV4 << endl;
00565     str << "  V3:     " << obj._dbV3 << endl;
00566     str << "  V3ToV4: " << obj._dbV3ToV4;
00567   }
00568   return str;
00569 }
00570 
00572 //
00573 //      CLASS NAME : librpmDb::db_const_iterator::D
00577 class librpmDb::db_const_iterator::D
00578 {
00579   D & operator=( const D & ); // NO ASSIGNMENT!
00580   D ( const D & );            // NO COPY!
00581 public:
00582 
00583   librpmDb::constPtr     _dbptr;
00584   shared_ptr<RpmException> _dberr;
00585 
00586   RpmHeader::constPtr _hptr;
00587   rpmdbMatchIterator   _mi;
00588 
00589   D( librpmDb::constPtr dbptr_r )
00590       : _dbptr( dbptr_r )
00591       , _mi( 0 )
00592   {
00593     if ( !_dbptr )
00594     {
00595       try
00596       {
00597         librpmDb::dbAccess( _dbptr );
00598       }
00599       catch (const RpmException & excpt_r)
00600       {
00601         ZYPP_CAUGHT(excpt_r);
00602       }
00603       if ( !_dbptr )
00604       {
00605         WAR << "No database access: " << _dberr << endl;
00606       }
00607     }
00608     else
00609     {
00610       destroy(); // Checks whether _dbptr still valid
00611     }
00612   }
00613 
00614   ~D()
00615   {
00616     if ( _mi )
00617     {
00618       ::rpmdbFreeIterator( _mi );
00619     }
00620   }
00621 
00626   bool create( int rpmtag, const void * keyp = NULL, size_t keylen = 0 )
00627   {
00628     destroy();
00629     if ( ! _dbptr )
00630       return false;
00631     _mi = ::rpmdbInitIterator( _dbptr->_d._db, rpmTag(rpmtag), keyp, keylen );
00632     return _mi;
00633   }
00634 
00639   bool destroy()
00640   {
00641     if ( _mi )
00642     {
00643       _mi = ::rpmdbFreeIterator( _mi );
00644       _hptr = 0;
00645     }
00646     if ( _dbptr && _dbptr->error() )
00647     {
00648       _dberr = _dbptr->error();
00649       WAR << "Lost database access: " << _dberr << endl;
00650       _dbptr = 0;
00651     }
00652     return false;
00653   }
00654 
00659   bool advance()
00660   {
00661     if ( !_mi )
00662       return false;
00663     Header h = ::rpmdbNextIterator( _mi );
00664     if ( ! h )
00665     {
00666       destroy();
00667       return false;
00668     }
00669     _hptr = new RpmHeader( h );
00670     return true;
00671   }
00672 
00676   bool init( int rpmtag, const void * keyp = NULL, size_t keylen = 0 )
00677   {
00678     if ( ! create( rpmtag, keyp, keylen ) )
00679       return false;
00680     return advance();
00681   }
00682 
00687   bool set( int off_r )
00688   {
00689     if ( ! create( RPMDBI_PACKAGES ) )
00690       return false;
00691 #warning TESTCASE: rpmdbAppendIterator and (non)sequential access?
00692     ::rpmdbAppendIterator( _mi, &off_r, 1 );
00693     return advance();
00694   }
00695 
00696   unsigned offset()
00697   {
00698     return( _mi ? ::rpmdbGetIteratorOffset( _mi ) : 0 );
00699   }
00700 
00701   int size()
00702   {
00703     if ( !_mi )
00704       return 0;
00705     int ret = ::rpmdbGetIteratorCount( _mi );
00706 #warning TESTCASE: rpmdbGetIteratorCount returns 0 on sequential access?
00707     return( ret ? ret : -1 ); // -1: sequential access
00708   }
00709 };
00710 
00712 
00714 //
00715 //      CLASS NAME : librpmDb::Ptr::db_const_iterator
00716 //
00718 
00720 //
00721 //
00722 //      METHOD NAME : librpmDb::db_const_iterator::db_iterator
00723 //      METHOD TYPE : Constructor
00724 //
00725 librpmDb::db_const_iterator::db_const_iterator( librpmDb::constPtr dbptr_r )
00726     : _d( * new D( dbptr_r ) )
00727 {
00728   findAll();
00729 }
00730 
00732 //
00733 //
00734 //      METHOD NAME : librpmDb::db_const_iterator::~db_const_iterator
00735 //      METHOD TYPE : Destructor
00736 //
00737 librpmDb::db_const_iterator::~db_const_iterator()
00738 {
00739   delete &_d;
00740 }
00741 
00743 //
00744 //
00745 //      METHOD NAME : librpmDb::db_const_iterator::operator++
00746 //      METHOD TYPE : void
00747 //
00748 void librpmDb::db_const_iterator::operator++()
00749 {
00750   _d.advance();
00751 }
00752 
00754 //
00755 //
00756 //      METHOD NAME : librpmDb::db_const_iterator::dbHdrNum
00757 //      METHOD TYPE : unsigned
00758 //
00759 unsigned librpmDb::db_const_iterator::dbHdrNum() const
00760 {
00761   return _d.offset();
00762 }
00763 
00765 //
00766 //
00767 //      METHOD NAME : librpmDb::db_const_iterator::operator*
00768 //      METHOD TYPE : const RpmHeader::constPtr &
00769 //
00770 const RpmHeader::constPtr & librpmDb::db_const_iterator::operator*() const
00771 {
00772   return _d._hptr;
00773 }
00774 
00776 //
00777 //
00778 //      METHOD NAME : librpmDb::db_const_iterator::dbError
00779 //      METHOD TYPE : PMError
00780 //
00781 shared_ptr<RpmException> librpmDb::db_const_iterator::dbError() const
00782 {
00783   if ( _d._dbptr )
00784     return _d._dbptr->error();
00785 
00786   return _d._dberr;
00787 }
00788 
00789 /******************************************************************
00790 **
00791 **
00792 **      FUNCTION NAME : operator<<
00793 **      FUNCTION TYPE : ostream &
00794 */
00795 ostream & operator<<( ostream & str, const librpmDb::db_const_iterator & obj )
00796 {
00797   str << "db_const_iterator(" << obj._d._dbptr
00798   << " Size:" << obj._d.size()
00799   << " HdrNum:" << obj._d.offset()
00800   << ")";
00801   return str;
00802 }
00803 
00805 //
00806 //
00807 //      METHOD NAME : librpmDb::db_const_iterator::findAll
00808 //      METHOD TYPE : bool
00809 //
00810 bool librpmDb::db_const_iterator::findAll()
00811 {
00812   return _d.init( RPMDBI_PACKAGES );
00813 }
00814 
00816 //
00817 //
00818 //      METHOD NAME : librpmDb::db_const_iterator::findByFile
00819 //      METHOD TYPE : bool
00820 //
00821 bool librpmDb::db_const_iterator::findByFile( const std::string & file_r )
00822 {
00823   return _d.init( RPMTAG_BASENAMES, file_r.c_str() );
00824 }
00825 
00827 //
00828 //
00829 //      METHOD NAME : librpmDb::db_const_iterator::findByProvides
00830 //      METHOD TYPE : bool
00831 //
00832 bool librpmDb::db_const_iterator::findByProvides( const std::string & tag_r )
00833 {
00834   return _d.init( RPMTAG_PROVIDENAME, tag_r.c_str() );
00835 }
00836 
00838 //
00839 //
00840 //      METHOD NAME : librpmDb::db_const_iterator::findByRequiredBy
00841 //      METHOD TYPE : bool
00842 //
00843 bool librpmDb::db_const_iterator::findByRequiredBy( const std::string & tag_r )
00844 {
00845   return _d.init( RPMTAG_REQUIRENAME, tag_r.c_str() );
00846 }
00847 
00849 //
00850 //
00851 //      METHOD NAME : librpmDb::db_const_iterator::findByConflicts
00852 //      METHOD TYPE : bool
00853 //
00854 bool librpmDb::db_const_iterator::findByConflicts( const std::string & tag_r )
00855 {
00856   return _d.init( RPMTAG_CONFLICTNAME, tag_r.c_str() );
00857 }
00858 
00860 //
00861 //
00862 //      METHOD NAME : librpmDb::findByName
00863 //      METHOD TYPE : bool
00864 //
00865 bool librpmDb::db_const_iterator::findByName( const string & name_r )
00866 {
00867   return _d.init( RPMTAG_NAME, name_r.c_str() );
00868 }
00869 
00871 //
00872 //
00873 //      METHOD NAME : librpmDb::db_const_iterator::findPackage
00874 //      METHOD TYPE : bool
00875 //
00876 bool librpmDb::db_const_iterator::findPackage( const string & name_r )
00877 {
00878   if ( ! _d.init( RPMTAG_NAME, name_r.c_str() ) )
00879     return false;
00880 
00881   if ( _d.size() == 1 )
00882     return true;
00883 
00884   // check installtime on multiple entries
00885   int match    = 0;
00886   time_t itime = 0;
00887   for ( ; operator*(); operator++() )
00888   {
00889     if ( operator*()->tag_installtime() > itime )
00890     {
00891       match = _d.offset();
00892       itime = operator*()->tag_installtime();
00893     }
00894   }
00895 
00896   return _d.set( match );
00897 }
00898 
00900 //
00901 //
00902 //      METHOD NAME : librpmDb::db_const_iterator::findPackage
00903 //      METHOD TYPE : bool
00904 //
00905 bool librpmDb::db_const_iterator::findPackage( const std::string & name_r, const Edition & ed_r )
00906 {
00907   if ( ! _d.init( RPMTAG_NAME, name_r.c_str() ) )
00908     return false;
00909 
00910   for ( ; operator*(); operator++() )
00911   {
00912     if ( ed_r == operator*()->tag_edition() )
00913     {
00914       int match = _d.offset();
00915       return _d.set( match );
00916     }
00917   }
00918 
00919   return _d.destroy();
00920 }
00921 
00923 //
00924 //
00925 //      METHOD NAME : librpmDb::db_const_iterator::findPackage
00926 //      METHOD TYPE : bool
00927 //
00928 bool librpmDb::db_const_iterator::findPackage( const Package::constPtr & which_r )
00929 {
00930   if ( ! which_r )
00931     return _d.destroy();
00932 
00933   return findPackage( which_r->name(), which_r->edition() );
00934 }
00935 
00936 } // namespace rpm
00937 } // namespace target
00938 } // namespace zypp

Generated on Tue Sep 25 19:23:09 2007 for libzypp by  doxygen 1.5.3