Detect and compile with rpm 4.7 (bnc #444211)
[platform/upstream/libzypp.git] / zypp / target / rpm / librpmDb.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/target/rpm/librpmDb.cc
10  *
11 */
12 #include "librpm.h"
13
14 #include <iostream>
15
16 #include "zypp/base/Logger.h"
17 #include "zypp/target/rpm/librpmDb.h"
18 #include "zypp/target/rpm/RpmHeader.h"
19 #include "zypp/target/rpm/RpmException.h"
20
21 using namespace std;
22
23 namespace zypp
24 {
25 namespace target
26 {
27 namespace rpm
28 {
29 ///////////////////////////////////////////////////////////////////
30 //
31 //      CLASS NAME : librpmDb::D
32 /**
33  * @short librpmDb internal database handle
34  **/
35 class librpmDb::D
36 {
37   D & operator=( const D & ); // NO ASSIGNMENT!
38   D ( const D & );            // NO COPY!
39 public:
40
41   const Pathname _root;   // root directory for all operations
42   const Pathname _dbPath; // directory (below root) that contains the rpmdb
43   rpmdb          _db;     // database handle
44   shared_ptr<RpmException> _error;  // database error
45
46   friend ostream & operator<<( ostream & str, const D & obj )
47   {
48     str << "{" << obj._error  << "(" << obj._root << ")" << obj._dbPath << "}";
49     return str;
50   }
51
52   D( const Pathname & root_r, const Pathname & dbPath_r, bool readonly_r )
53       : _root  ( root_r )
54       , _dbPath( dbPath_r )
55       , _db    ( 0 )
56   {
57     _error.reset();
58     // set %_dbpath macro
59     ::addMacro( NULL, "_dbpath", NULL, _dbPath.asString().c_str(), RMIL_CMDLINE );
60     const char * root = ( _root == "/" ? NULL : _root.asString().c_str() );
61     int          perms = 0644;
62
63     // check whether to create a new db
64     PathInfo master( _root + _dbPath + "Packages" );
65     if ( ! master.isFile() )
66     {
67       // init database
68       int res = ::rpmdbInit( root, perms );
69       if ( res )
70       {
71         ERR << "rpmdbInit error(" << res << "): " << *this << endl;
72         _error = shared_ptr<RpmInitException>(new RpmInitException(_root, _dbPath));
73         ZYPP_THROW(*_error);
74       }
75     }
76
77     // open database
78     int res = ::rpmdbOpen( root, &_db, (readonly_r ? O_RDONLY : O_RDWR ), perms );
79     if ( res || !_db )
80     {
81       if ( _db )
82       {
83         ::rpmdbClose( _db );
84         _db = 0;
85       }
86       ERR << "rpmdbOpen error(" << res << "): " << *this << endl;
87       _error = shared_ptr<RpmDbOpenException>(new RpmDbOpenException(_root, _dbPath));
88       ZYPP_THROW(*_error);
89       return;
90     }
91
92     DBG << "DBACCESS " << *this << endl;
93   }
94
95   ~D()
96   {
97     if ( _db )
98     {
99       ::rpmdbClose( _db );
100     }
101   }
102 };
103
104 ///////////////////////////////////////////////////////////////////
105
106 ///////////////////////////////////////////////////////////////////
107 //
108 //      CLASS NAME : librpmDb (ststic interface)
109 //
110 ///////////////////////////////////////////////////////////////////
111
112 Pathname         librpmDb::_defaultRoot  ( "/" );
113 Pathname         librpmDb::_defaultDbPath( "/var/lib/rpm" );
114 librpmDb::constPtr librpmDb::_defaultDb;
115 bool             librpmDb::_dbBlocked    ( true );
116
117 ///////////////////////////////////////////////////////////////////
118 //
119 //
120 //      METHOD NAME : librpmDb::globalInit
121 //      METHOD TYPE : bool
122 //
123 bool librpmDb::globalInit()
124 {
125   static bool initialized = false;
126
127   if ( initialized )
128     return true;
129
130   int rc = ::rpmReadConfigFiles( NULL, NULL );
131   if ( rc )
132   {
133     ERR << "rpmReadConfigFiles returned " << rc << endl;
134     return false;
135   }
136
137   // should speed up convertdb and rebuilddb.
138   ::addMacro( NULL, "_rpmdb_rebuild", NULL, "%{nil}", RMIL_CMDLINE );
139
140   initialized = true; // Necessary to be able to use exand().
141
142 #define OUTVAL(n) << " (" #n ":" << expand( "%{" #n "}" ) << ")"
143   MIL << "librpm init done:"
144   OUTVAL(_target)
145   OUTVAL(_dbpath)
146   << endl;
147 #undef OUTVAL
148   return initialized;
149 }
150
151 ///////////////////////////////////////////////////////////////////
152 //
153 //
154 //      METHOD NAME : librpmDb::expand
155 //      METHOD TYPE : std::string
156 //
157 std::string librpmDb::expand( const std::string & macro_r )
158 {
159   if ( ! globalInit() )
160     return macro_r;  // unexpanded
161
162   char * val = ::rpmExpand( macro_r.c_str(), NULL );
163   if ( !val )
164     return "";
165
166   string ret( val );
167   free( val );
168   return ret;
169 }
170
171 ///////////////////////////////////////////////////////////////////
172 //
173 //
174 //      METHOD NAME : librpmDb::newLibrpmDb
175 //      METHOD TYPE : librpmDb *
176 //
177 librpmDb * librpmDb::newLibrpmDb( Pathname root_r, Pathname dbPath_r, bool readonly_r )
178 {
179   // check arguments
180   if ( ! (root_r.absolute() && dbPath_r.absolute()) )
181   {
182     ZYPP_THROW(RpmInvalidRootException(root_r, dbPath_r));
183   }
184
185   // initialize librpm
186   if ( ! globalInit() )
187   {
188     ZYPP_THROW(GlobalRpmInitException());
189   }
190
191   // open rpmdb
192   librpmDb * ret = 0;
193   try
194   {
195     ret = new librpmDb( root_r, dbPath_r, readonly_r );
196   }
197   catch (const RpmException & excpt_r)
198   {
199     ZYPP_CAUGHT(excpt_r);
200     delete ret;
201     ret = 0;
202     ZYPP_RETHROW(excpt_r);
203   }
204   return ret;
205 }
206
207 ///////////////////////////////////////////////////////////////////
208 //
209 //
210 //      METHOD NAME : librpmDb::dbAccess
211 //      METHOD TYPE : PMError
212 //
213 void librpmDb::dbAccess( const Pathname & root_r, const Pathname & dbPath_r )
214 {
215   // check arguments
216   if ( ! (root_r.absolute() && dbPath_r.absolute()) )
217   {
218     ZYPP_THROW(RpmInvalidRootException(root_r, dbPath_r));
219   }
220
221   if ( _defaultDb )
222   {
223     // already accessing a database: switching is not allowed.
224     if ( _defaultRoot == root_r && _defaultDbPath == dbPath_r )
225       return;
226     else
227     {
228       ZYPP_THROW(RpmDbAlreadyOpenException(_defaultRoot, _defaultDbPath, root_r, dbPath_r));
229     }
230   }
231
232   // got no database: we could switch to a new one (even if blocked!)
233   _defaultRoot = root_r;
234   _defaultDbPath = dbPath_r;
235   MIL << "Set new database location: " << stringPath( _defaultRoot, _defaultDbPath ) << endl;
236
237   return dbAccess();
238 }
239
240 ///////////////////////////////////////////////////////////////////
241 //
242 //
243 //      METHOD NAME : librpmDb::dbAccess
244 //      METHOD TYPE : PMError
245 //
246 void librpmDb::dbAccess()
247 {
248   if ( _dbBlocked )
249   {
250     ZYPP_THROW(RpmAccessBlockedException(_defaultRoot, _defaultDbPath));
251   }
252
253   if ( !_defaultDb )
254   {
255     // get access
256     _defaultDb = newLibrpmDb( _defaultRoot, _defaultDbPath, /*readonly*/true );
257   }
258 }
259
260 ///////////////////////////////////////////////////////////////////
261 //
262 //
263 //      METHOD NAME : librpmDb::dbAccess
264 //      METHOD TYPE : PMError
265 //
266 void librpmDb::dbAccess( librpmDb::constPtr & ptr_r )
267 {
268   try
269   {
270     dbAccess();
271   }
272   catch (const RpmException & excpt_r)
273   {
274     ZYPP_CAUGHT(excpt_r);
275     ptr_r = 0;
276     ZYPP_RETHROW(excpt_r);
277   }
278   ptr_r = _defaultDb;
279 }
280
281 ///////////////////////////////////////////////////////////////////
282 //
283 //
284 //      METHOD NAME : librpmDb::dbRelease
285 //      METHOD TYPE : unsigned
286 //
287 unsigned librpmDb::dbRelease( bool force_r )
288 {
289   if ( !_defaultDb )
290   {
291     return 0;
292   }
293
294   unsigned outstanding = _defaultDb->refCount() - 1; // refCount can't be 0
295
296   switch ( outstanding )
297   {
298   default:
299     if ( !force_r )
300     {
301       DBG << "dbRelease: keep access, outstanding " << outstanding << endl;
302       break;
303     }
304     // else fall through:
305   case 0:
306     DBG << "dbRelease: release" << (force_r && outstanding ? "(forced)" : "")
307     << ", outstanding " << outstanding << endl;
308
309     _defaultDb->_d._error = shared_ptr<RpmAccessBlockedException>(new RpmAccessBlockedException(_defaultDb->_d._root, _defaultDb->_d._dbPath));
310     // tag handle invalid
311     _defaultDb = 0;
312     break;
313   }
314
315   return outstanding;
316 }
317
318 ///////////////////////////////////////////////////////////////////
319 //
320 //
321 //      METHOD NAME : librpmDb::blockAccess
322 //      METHOD TYPE : unsigned
323 //
324 unsigned librpmDb::blockAccess()
325 {
326   MIL << "Block access" << endl;
327   _dbBlocked = true;
328   return dbRelease( /*force*/true );
329 }
330
331 ///////////////////////////////////////////////////////////////////
332 //
333 //
334 //      METHOD NAME : librpmDb::unblockAccess
335 //      METHOD TYPE : void
336 //
337 void librpmDb::unblockAccess()
338 {
339   MIL << "Unblock access" << endl;
340   _dbBlocked = false;
341 }
342
343 ///////////////////////////////////////////////////////////////////
344 //
345 //
346 //      METHOD NAME : librpmDb::dumpState
347 //      METHOD TYPE : ostream &
348 //
349 ostream & librpmDb::dumpState( ostream & str )
350 {
351   if ( !_defaultDb )
352   {
353     return str << "[librpmDb " << (_dbBlocked?"BLOCKED":"CLOSED") << " " << stringPath( _defaultRoot, _defaultDbPath ) << "]";
354   }
355   return str << "[" << _defaultDb << "]";
356 }
357
358 ///////////////////////////////////////////////////////////////////
359 //
360 //      CLASS NAME : librpmDb (internal database handle interface (nonstatic))
361 //
362 ///////////////////////////////////////////////////////////////////
363
364 ///////////////////////////////////////////////////////////////////
365 //
366 //
367 //      METHOD NAME : librpmDb::librpmDb
368 //      METHOD TYPE : Constructor
369 //
370 //      DESCRIPTION :
371 //
372 librpmDb::librpmDb( const Pathname & root_r, const Pathname & dbPath_r, bool readonly_r )
373     : _d( * new D( root_r, dbPath_r, readonly_r ) )
374 {}
375
376 ///////////////////////////////////////////////////////////////////
377 //
378 //
379 //      METHOD NAME : librpmDb::~librpmDb
380 //      METHOD TYPE : Destructor
381 //
382 //      DESCRIPTION :
383 //
384 librpmDb::~librpmDb()
385 {
386   delete &_d;
387 }
388
389 ///////////////////////////////////////////////////////////////////
390 //
391 //
392 //      METHOD NAME : librpmDb::unref_to
393 //      METHOD TYPE : void
394 //
395 void librpmDb::unref_to( unsigned refCount_r ) const
396 {
397   if ( refCount_r == 1 )
398   {
399     dbRelease();
400   }
401 }
402
403 ///////////////////////////////////////////////////////////////////
404 //
405 //
406 //      METHOD NAME : librpmDb::root
407 //      METHOD TYPE : const Pathname &
408 //
409 const Pathname & librpmDb::root() const
410 {
411   return _d._root;
412 }
413
414 ///////////////////////////////////////////////////////////////////
415 //
416 //
417 //      METHOD NAME : librpmDb::dbPath
418 //      METHOD TYPE : const Pathname &
419 //
420 const Pathname & librpmDb::dbPath() const
421 {
422   return _d._dbPath;
423 }
424
425 ///////////////////////////////////////////////////////////////////
426 //
427 //
428 //      METHOD NAME : librpmDb::error
429 //      METHOD TYPE : PMError
430 //
431 shared_ptr<RpmException> librpmDb::error() const
432 {
433   return _d._error;
434 }
435
436 ///////////////////////////////////////////////////////////////////
437 //
438 //
439 //      METHOD NAME : librpmDb::empty
440 //      METHOD TYPE : bool
441 //
442 bool librpmDb::empty() const
443 {
444   return( valid() && ! *db_const_iterator( this ) );
445 }
446
447 ///////////////////////////////////////////////////////////////////
448 //
449 //
450 //      METHOD NAME : librpmDb::size
451 //      METHOD TYPE : unsigned
452 //
453 unsigned librpmDb::size() const
454 {
455   unsigned count = 0;
456   if ( valid() )
457   {
458 #ifdef _RPM_4_4_COMPAT
459     // looks like rpm-4.7 has no public dbi interface anymore
460     int dbi = ::rpmdbOpen("/", &_d._db, O_RDONLY, 0);
461     if (dbi == 0) {
462         rpmdbMatchIterator mi = ::rpmdbInitIterator(_d._db, RPMTAG_NAME, NULL, 0);
463         if (mi != NULL) {
464             rpmtd item;
465             for (;;) {
466                 Header rpmHeader = ::rpmdbNextIterator(mi);
467                 if (rpmHeader != NULL)
468                     ++count;
469             }
470         }
471         ::rpmdbClose(_d._db);
472     }
473 #else
474     dbiIndex dbi = dbiOpen( _d._db, RPMTAG_NAME, 0 );
475     if ( dbi )
476     {
477       DBC * dbcursor = 0;
478       dbiCopen( dbi, dbi->dbi_txnid, &dbcursor, 0 );
479
480       DBT key, data;
481       memset( &key, 0, sizeof(key) );
482       memset( &data, 0, sizeof(data) );
483       while ( dbiGet( dbi, dbcursor, &key, &data, DB_NEXT ) == 0 )
484         count += data.size / dbi->dbi_jlen;
485
486       dbiCclose( dbi, dbcursor, 0 );
487       /* no need to close dbi */
488     }
489 #endif
490   }
491   return count;
492 }
493
494 ///////////////////////////////////////////////////////////////////
495 //
496 //
497 //      METHOD NAME : librpmDb::dont_call_it
498 //      METHOD TYPE : void *
499 //
500 void * librpmDb::dont_call_it() const
501 {
502   return _d._db;
503 }
504
505 ///////////////////////////////////////////////////////////////////
506 //
507 //
508 //      METHOD NAME : librpmDb::dumpOn
509 //      METHOD TYPE : ostream &
510 //
511 //      DESCRIPTION :
512 //
513 ostream & librpmDb::dumpOn( ostream & str ) const
514 {
515   ReferenceCounted::dumpOn( str ) << _d;
516   return str;
517 }
518
519 ///////////////////////////////////////////////////////////////////
520 //
521 //      CLASS NAME : librpmDb::DbDirInfo
522 //
523 ///////////////////////////////////////////////////////////////////
524
525 ///////////////////////////////////////////////////////////////////
526 //
527 //
528 //      METHOD NAME : librpmDb::DbDirInfo::DbDirInfo
529 //      METHOD TYPE : Constructor
530 //
531 librpmDb::DbDirInfo::DbDirInfo( const Pathname & root_r, const Pathname & dbPath_r )
532     : _root( root_r )
533     , _dbPath( dbPath_r )
534 {
535   // check and adjust arguments
536   if ( ! (root_r.absolute() && dbPath_r.absolute()) )
537   {
538     ERR << "Relative path for root(" << _root << ") or dbPath(" << _dbPath << ")" << endl;
539   }
540   else
541   {
542     _dbDir   ( _root + _dbPath );
543     _dbV4    ( _dbDir.path() + "Packages" );
544     _dbV3    ( _dbDir.path() + "packages.rpm" );
545     _dbV3ToV4( _dbDir.path() + "packages.rpm3" );
546     DBG << *this << endl;
547   }
548 }
549
550 ///////////////////////////////////////////////////////////////////
551 //
552 //
553 //      METHOD NAME : librpmDb::DbDirInfo::update
554 //      METHOD TYPE : void
555 //
556 void librpmDb::DbDirInfo::restat()
557 {
558   _dbDir();
559   _dbV4();
560   _dbV3();
561   _dbV3ToV4();
562   DBG << *this << endl;
563 }
564
565 /******************************************************************
566 **
567 **
568 **      FUNCTION NAME : operator<<
569 **      FUNCTION TYPE : std::ostream &
570 */
571 std::ostream & operator<<( std::ostream & str, const librpmDb::DbDirInfo & obj )
572 {
573   if ( obj.illegalArgs() )
574   {
575     str << "ILLEGAL: '(" << obj.root() << ")" << obj.dbPath() << "'";
576   }
577   else
578   {
579     str << "'(" << obj.root() << ")" << obj.dbPath() << "':" << endl;
580     str << "  Dir:    " << obj._dbDir << endl;
581     str << "  V4:     " << obj._dbV4 << endl;
582     str << "  V3:     " << obj._dbV3 << endl;
583     str << "  V3ToV4: " << obj._dbV3ToV4;
584   }
585   return str;
586 }
587
588 ///////////////////////////////////////////////////////////////////
589 //
590 //      CLASS NAME : librpmDb::db_const_iterator::D
591 /**
592  *
593  **/
594 class librpmDb::db_const_iterator::D
595 {
596   D & operator=( const D & ); // NO ASSIGNMENT!
597   D ( const D & );            // NO COPY!
598 public:
599
600   librpmDb::constPtr     _dbptr;
601   shared_ptr<RpmException> _dberr;
602
603   RpmHeader::constPtr _hptr;
604   rpmdbMatchIterator   _mi;
605
606   D( librpmDb::constPtr dbptr_r )
607       : _dbptr( dbptr_r )
608       , _mi( 0 )
609   {
610     if ( !_dbptr )
611     {
612       try
613       {
614         librpmDb::dbAccess( _dbptr );
615       }
616       catch (const RpmException & excpt_r)
617       {
618         ZYPP_CAUGHT(excpt_r);
619       }
620       if ( !_dbptr )
621       {
622         WAR << "No database access: " << _dberr << endl;
623       }
624     }
625     else
626     {
627       destroy(); // Checks whether _dbptr still valid
628     }
629   }
630
631   ~D()
632   {
633     if ( _mi )
634     {
635       ::rpmdbFreeIterator( _mi );
636     }
637   }
638
639   /**
640    * Let iterator access a dbindex file. Call @ref advance to access the
641    * 1st element (if present).
642    **/
643   bool create( int rpmtag, const void * keyp = NULL, size_t keylen = 0 )
644   {
645     destroy();
646     if ( ! _dbptr )
647       return false;
648     _mi = ::rpmdbInitIterator( _dbptr->_d._db, rpmTag(rpmtag), keyp, keylen );
649     return _mi;
650   }
651
652   /**
653    * Destroy iterator. Invalidates _dbptr, if database was blocked meanwile.
654    * Always returns false.
655    **/
656   bool destroy()
657   {
658     if ( _mi )
659     {
660       _mi = ::rpmdbFreeIterator( _mi );
661       _hptr = 0;
662     }
663     if ( _dbptr && _dbptr->error() )
664     {
665       _dberr = _dbptr->error();
666       WAR << "Lost database access: " << _dberr << endl;
667       _dbptr = 0;
668     }
669     return false;
670   }
671
672   /**
673    * Advance to the first/next header in iterator. Destroys iterator if
674    * no more headers available.
675    **/
676   bool advance()
677   {
678     if ( !_mi )
679       return false;
680     Header h = ::rpmdbNextIterator( _mi );
681     if ( ! h )
682     {
683       destroy();
684       return false;
685     }
686     _hptr = new RpmHeader( h );
687     return true;
688   }
689
690   /**
691    * Access a dbindex file and advance to the 1st header.
692    **/
693   bool init( int rpmtag, const void * keyp = NULL, size_t keylen = 0 )
694   {
695     if ( ! create( rpmtag, keyp, keylen ) )
696       return false;
697     return advance();
698   }
699
700   /**
701    * Create an itertator that contains the database entry located at
702    * off_r, and advance to the 1st header.
703    **/
704   bool set( int off_r )
705   {
706     if ( ! create( RPMDBI_PACKAGES ) )
707       return false;
708 #warning TESTCASE: rpmdbAppendIterator and (non)sequential access?
709     ::rpmdbAppendIterator( _mi, &off_r, 1 );
710     return advance();
711   }
712
713   unsigned offset()
714   {
715     return( _mi ? ::rpmdbGetIteratorOffset( _mi ) : 0 );
716   }
717
718   int size()
719   {
720     if ( !_mi )
721       return 0;
722     int ret = ::rpmdbGetIteratorCount( _mi );
723 #warning TESTCASE: rpmdbGetIteratorCount returns 0 on sequential access?
724     return( ret ? ret : -1 ); // -1: sequential access
725   }
726 };
727
728 ///////////////////////////////////////////////////////////////////
729
730 ///////////////////////////////////////////////////////////////////
731 //
732 //      CLASS NAME : librpmDb::Ptr::db_const_iterator
733 //
734 ///////////////////////////////////////////////////////////////////
735
736 ///////////////////////////////////////////////////////////////////
737 //
738 //
739 //      METHOD NAME : librpmDb::db_const_iterator::db_iterator
740 //      METHOD TYPE : Constructor
741 //
742 librpmDb::db_const_iterator::db_const_iterator( librpmDb::constPtr dbptr_r )
743     : _d( * new D( dbptr_r ) )
744 {
745   findAll();
746 }
747
748 ///////////////////////////////////////////////////////////////////
749 //
750 //
751 //      METHOD NAME : librpmDb::db_const_iterator::~db_const_iterator
752 //      METHOD TYPE : Destructor
753 //
754 librpmDb::db_const_iterator::~db_const_iterator()
755 {
756   delete &_d;
757 }
758
759 ///////////////////////////////////////////////////////////////////
760 //
761 //
762 //      METHOD NAME : librpmDb::db_const_iterator::operator++
763 //      METHOD TYPE : void
764 //
765 void librpmDb::db_const_iterator::operator++()
766 {
767   _d.advance();
768 }
769
770 ///////////////////////////////////////////////////////////////////
771 //
772 //
773 //      METHOD NAME : librpmDb::db_const_iterator::dbHdrNum
774 //      METHOD TYPE : unsigned
775 //
776 unsigned librpmDb::db_const_iterator::dbHdrNum() const
777 {
778   return _d.offset();
779 }
780
781 ///////////////////////////////////////////////////////////////////
782 //
783 //
784 //      METHOD NAME : librpmDb::db_const_iterator::operator*
785 //      METHOD TYPE : const RpmHeader::constPtr &
786 //
787 const RpmHeader::constPtr & librpmDb::db_const_iterator::operator*() const
788 {
789   return _d._hptr;
790 }
791
792 ///////////////////////////////////////////////////////////////////
793 //
794 //
795 //      METHOD NAME : librpmDb::db_const_iterator::dbError
796 //      METHOD TYPE : PMError
797 //
798 shared_ptr<RpmException> librpmDb::db_const_iterator::dbError() const
799 {
800   if ( _d._dbptr )
801     return _d._dbptr->error();
802
803   return _d._dberr;
804 }
805
806 /******************************************************************
807 **
808 **
809 **      FUNCTION NAME : operator<<
810 **      FUNCTION TYPE : ostream &
811 */
812 ostream & operator<<( ostream & str, const librpmDb::db_const_iterator & obj )
813 {
814   str << "db_const_iterator(" << obj._d._dbptr
815   << " Size:" << obj._d.size()
816   << " HdrNum:" << obj._d.offset()
817   << ")";
818   return str;
819 }
820
821 ///////////////////////////////////////////////////////////////////
822 //
823 //
824 //      METHOD NAME : librpmDb::db_const_iterator::findAll
825 //      METHOD TYPE : bool
826 //
827 bool librpmDb::db_const_iterator::findAll()
828 {
829   return _d.init( RPMDBI_PACKAGES );
830 }
831
832 ///////////////////////////////////////////////////////////////////
833 //
834 //
835 //      METHOD NAME : librpmDb::db_const_iterator::findByFile
836 //      METHOD TYPE : bool
837 //
838 bool librpmDb::db_const_iterator::findByFile( const std::string & file_r )
839 {
840   return _d.init( RPMTAG_BASENAMES, file_r.c_str() );
841 }
842
843 ///////////////////////////////////////////////////////////////////
844 //
845 //
846 //      METHOD NAME : librpmDb::db_const_iterator::findByProvides
847 //      METHOD TYPE : bool
848 //
849 bool librpmDb::db_const_iterator::findByProvides( const std::string & tag_r )
850 {
851   return _d.init( RPMTAG_PROVIDENAME, tag_r.c_str() );
852 }
853
854 ///////////////////////////////////////////////////////////////////
855 //
856 //
857 //      METHOD NAME : librpmDb::db_const_iterator::findByRequiredBy
858 //      METHOD TYPE : bool
859 //
860 bool librpmDb::db_const_iterator::findByRequiredBy( const std::string & tag_r )
861 {
862   return _d.init( RPMTAG_REQUIRENAME, tag_r.c_str() );
863 }
864
865 ///////////////////////////////////////////////////////////////////
866 //
867 //
868 //      METHOD NAME : librpmDb::db_const_iterator::findByConflicts
869 //      METHOD TYPE : bool
870 //
871 bool librpmDb::db_const_iterator::findByConflicts( const std::string & tag_r )
872 {
873   return _d.init( RPMTAG_CONFLICTNAME, tag_r.c_str() );
874 }
875
876 ///////////////////////////////////////////////////////////////////
877 //
878 //
879 //      METHOD NAME : librpmDb::findByName
880 //      METHOD TYPE : bool
881 //
882 bool librpmDb::db_const_iterator::findByName( const string & name_r )
883 {
884   return _d.init( RPMTAG_NAME, name_r.c_str() );
885 }
886
887 ///////////////////////////////////////////////////////////////////
888 //
889 //
890 //      METHOD NAME : librpmDb::db_const_iterator::findPackage
891 //      METHOD TYPE : bool
892 //
893 bool librpmDb::db_const_iterator::findPackage( const string & name_r )
894 {
895   if ( ! _d.init( RPMTAG_NAME, name_r.c_str() ) )
896     return false;
897
898   if ( _d.size() == 1 )
899     return true;
900
901   // check installtime on multiple entries
902   int match    = 0;
903   time_t itime = 0;
904   for ( ; operator*(); operator++() )
905   {
906     if ( operator*()->tag_installtime() > itime )
907     {
908       match = _d.offset();
909       itime = operator*()->tag_installtime();
910     }
911   }
912
913   return _d.set( match );
914 }
915
916 ///////////////////////////////////////////////////////////////////
917 //
918 //
919 //      METHOD NAME : librpmDb::db_const_iterator::findPackage
920 //      METHOD TYPE : bool
921 //
922 bool librpmDb::db_const_iterator::findPackage( const std::string & name_r, const Edition & ed_r )
923 {
924   if ( ! _d.init( RPMTAG_NAME, name_r.c_str() ) )
925     return false;
926
927   for ( ; operator*(); operator++() )
928   {
929     if ( ed_r == operator*()->tag_edition() )
930     {
931       int match = _d.offset();
932       return _d.set( match );
933     }
934   }
935
936   return _d.destroy();
937 }
938
939 ///////////////////////////////////////////////////////////////////
940 //
941 //
942 //      METHOD NAME : librpmDb::db_const_iterator::findPackage
943 //      METHOD TYPE : bool
944 //
945 bool librpmDb::db_const_iterator::findPackage( const Package::constPtr & which_r )
946 {
947   if ( ! which_r )
948     return _d.destroy();
949
950   return findPackage( which_r->name(), which_r->edition() );
951 }
952
953 } // namespace rpm
954 } // namespace target
955 } // namespace zypp