QueueItemInstall.cc

Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
00002 /* QueueItemInstall.cc
00003  *
00004  * Copyright (C) 2000-2002 Ximian, Inc.
00005  * Copyright (C) 2005 SUSE Linux Products GmbH
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License,
00009  * version 2, as published by the Free Software Foundation.
00010  *
00011  * This program is distributed in the hope that it will be useful, but
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019  * 02111-1307, USA.
00020  */
00021 
00022 #include "zypp/CapFactory.h"
00023 #include "zypp/CapSet.h"
00024 #include "zypp/Package.h"
00025 #include "zypp/base/Logger.h"
00026 #include "zypp/base/String.h"
00027 #include "zypp/base/Gettext.h"
00028 
00029 #include "zypp/base/Algorithm.h"
00030 #include "zypp/ResPool.h"
00031 #include "zypp/ResFilters.h"
00032 #include "zypp/CapFilters.h"
00033 
00034 #include "zypp/solver/detail/QueueItemInstall.h"
00035 #include "zypp/solver/detail/QueueItemEstablish.h"
00036 #include "zypp/solver/detail/QueueItemUninstall.h"
00037 #include "zypp/solver/detail/QueueItemRequire.h"
00038 #include "zypp/solver/detail/QueueItemConflict.h"
00039 #include "zypp/solver/detail/QueueItem.h"
00040 #include "zypp/solver/detail/ResolverContext.h"
00041 #include "zypp/solver/detail/ResolverInfoConflictsWith.h"
00042 #include "zypp/solver/detail/ResolverInfoMisc.h"
00043 #include "zypp/solver/detail/ResolverInfoNeededBy.h"
00044 #include "zypp/solver/detail/Helper.h"
00045 
00047 namespace zypp
00048 { 
00049 
00050   namespace solver
00051   { 
00052 
00053     namespace detail
00054     { 
00055 
00056 using namespace std;
00057 
00058 IMPL_PTR_TYPE(QueueItemInstall);
00059 
00060 //---------------------------------------------------------------------------
00061 
00062 std::ostream &
00063 QueueItemInstall::dumpOn( std::ostream & os ) const
00064 {
00065     os << "[" << (_soft?"Soft":"") << "Install: ";
00066     os << _item;
00067     if (_upgrades) {
00068         os << ", Upgrades ";
00069         os << _upgrades;
00070     }
00071     if (!_deps_satisfied_by_this_install.empty()) {
00072         os << ", Satisfies [";
00073         for (CapSet::const_iterator iter = _deps_satisfied_by_this_install.begin();
00074             iter != _deps_satisfied_by_this_install.end(); iter++)
00075         {
00076             if (iter != _deps_satisfied_by_this_install.begin()) os << ", ";
00077             os << (*iter);
00078         }
00079         os << "]";
00080     }
00081     if (!_needed_by.empty()) {
00082         os << ", Needed by ";
00083         for (PoolItemList::const_iterator it = _needed_by.begin(); it != _needed_by.end(); ++it) {
00084             if (it != _needed_by.begin()) os << ", ";
00085             os << *it;
00086         }
00087     }
00088     if (_explicitly_requested) os << ", Explicit !";
00089     os << "]";
00090     return os;
00091 }
00092 
00093 //---------------------------------------------------------------------------
00094 
00095 QueueItemInstall::QueueItemInstall (const ResPool & pool, PoolItem_Ref item, bool soft)
00096     : QueueItem (QUEUE_ITEM_TYPE_INSTALL, pool)
00097     , _item (item)
00098     , _soft (soft)
00099     , _channel_priority (0)
00100     , _other_penalty (0)
00101     , _explicitly_requested (false)
00102 {
00103     Resolvable::constPtr res = item.resolvable();
00104 
00105     // Atoms are by default parallel installable (cf #181103)
00106     bool install_in_parallel = isKind<Atom>( res );
00107 
00108     // if its not an atom, check if its a package with 'install-only' set
00109     if (!install_in_parallel) {
00110         Package::constPtr pkg = asKind<Package>( res );
00111         install_in_parallel = (pkg != NULL) && pkg->installOnly();
00112     }
00113 
00114     // if its not parallel installable
00115     //   check if this install upgrades anything
00116 
00117     if (!install_in_parallel) {
00118         _upgrades = Helper::findInstalledItem (pool, item);
00119     }
00120 
00121     _XDEBUG("QueueItemInstall::QueueItemInstall(" << item << (soft?", soft":"") << ") upgrades " << _upgrades);
00122 }
00123  
00124 
00125 QueueItemInstall::~QueueItemInstall()
00126 {
00127 }
00128 
00129 //---------------------------------------------------------------------------
00130 
00131 bool
00132 QueueItemInstall::isSatisfied (ResolverContext_Ptr context) const
00133 {
00134     return context->isPresent (_item);
00135 }
00136 
00137 
00138 //---------------------------------------------------------------------------
00139 
00140 // Handle items which freshen or supplement us -> re-establish them
00141 
00142 // see also FreshenState in Resolver.cc
00143 // see also UninstallEstablishItem in QueueItemUninstall.cc
00144 
00145 typedef map<string, PoolItem_Ref> EstablishMap;
00146 
00147 struct InstallEstablishItem
00148 {
00149     EstablishMap establishmap;
00150 
00151     InstallEstablishItem ()
00152     { }
00153 
00154 
00155     // provider has a freshens on a just to-be-installed item
00156     //   re-establish provider, maybe its incomplete now
00157 
00158     bool operator()( const CapAndItem & cai )
00159     {
00160         _XDEBUG("QueueItemInstall::InstallEstablishItem (" << cai.item << ", " << cai.cap << ")");
00161 
00162         // only consider best architecture, best edition
00163 
00164         PoolItem_Ref item( cai.item );
00165 
00166         EstablishMap::iterator it = establishmap.find( item->name() );
00167 
00168         if (it != establishmap.end()) {                                 // item with same name found
00169             int cmp = it->second->arch().compare( item->arch() );
00170             if (cmp < 0) {                                              // new item has better arch
00171                 it->second = item;
00172             }
00173             else if (cmp == 0) {                                        // new item has equal arch
00174                 if (it->second->edition().compare( item->edition() ) < 0) {
00175                     it->second = item;                          // new item has better edition
00176                 }
00177             }
00178         }
00179         else {
00180             establishmap[item->name()] = item;
00181         }
00182         return true;
00183     }
00184 };
00185 
00186 
00187 
00188 //---------------------------------------------------------------------------
00189 
00190 // Handle items which conflict us -> uninstall them
00191 
00192 struct UninstallConflicting
00193 {
00194     ResolverContext_Ptr _context;
00195     const Capability _provided_cap;
00196     PoolItem _install_item;             // the to-be-installed item issuing the conflict
00197     PoolItem _upgrade_item;             // the installed, to-be-upgraded item (might be empty if its a fresh install)
00198     QueueItemList & _qil;
00199     bool ignored;
00200 
00201     UninstallConflicting( ResolverContext_Ptr ctx, const Capability & provided_cap, PoolItem install_item, PoolItem upgrade_item, QueueItemList & qil )
00202         : _context( ctx )
00203         , _provided_cap( provided_cap )
00204         , _install_item( install_item )
00205         , _upgrade_item( upgrade_item )
00206         , _qil( qil )
00207         , ignored( false )
00208     { }
00209 
00210 
00211     // conflicting_item provides a capability (conflicting_cap), _install_item lists as conflicts.
00212 
00213     bool operator()( const CapAndItem & cai)
00214     {
00215         PoolItem_Ref conflicting_item = cai.item;
00216 
00217         _XDEBUG("UninstallConflicting(" << conflicting_item << ", cap " << cai.cap << ")");
00218 
00219         if (conflicting_item == _install_item) {                                // self conflict ?
00220             WAR << "Ignoring self-conflicts" << endl;
00221             return true;
00222         }
00223         if (conflicting_item == _upgrade_item) {                                // upgrade conflict ?
00224             _XDEBUG("We're upgrading the conflicting item");
00225             return true;
00226         }
00227 
00228         const Capability conflicting_cap = cai.cap;
00229         ResolverInfo_Ptr log_info;
00230         QueueItemUninstall_Ptr uninstall_item;
00231 
00232         IgnoreMap ignoreMap = _context->getIgnoreConflicts();           // ignored conflict ?
00233         // checking for ignoring dependencies
00234         for (IgnoreMap::iterator it = ignoreMap.begin(); it != ignoreMap.end(); it++) {
00235             if (it->first == conflicting_item
00236                 && it->second == conflicting_cap)
00237             {
00238                 _XDEBUG("Found ignoring conflicts " << conflicting_cap << " for " << conflicting_item);
00239                 ignored = true;
00240                 return false;           // stop iteration
00241             } else {
00242                 _XDEBUG("Ignoring conflict " << it->second << " for " <<  it->first << " does not fit");            
00243             }
00244         }
00245 
00246         /* Check to see if we conflict with ourself and don't create
00247          * an uninstall item for it if we do.  This is Debian's way of
00248          * saying that one and only one item with this provide may
00249          * exist on the system at a time.
00250          */
00251 
00252         if (compareByNVR (conflicting_item.resolvable(), _install_item.resolvable()) == 0) {
00253                 return true;
00254         }
00255 
00256 #warning Make behaviour configurable
00257         // If the package is installed or is set to be installed by the user,
00258         // let the user decide deleting conflicting package. This is only an info.
00259         // Try at first updating packages.
00260         //
00261         ResStatus confl_status = _context->getStatus( conflicting_item );
00262         if (confl_status.isToBeInstalled()                      // scheduled for installation
00263             || confl_status.staysInstalled())                   // not scheduled at all but installed
00264         {
00265             ResolverInfoMisc_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL,
00266                                                                                _install_item, RESOLVER_INFO_PRIORITY_VERBOSE, _provided_cap);
00267             misc_info->setOtherPoolItem (conflicting_item);
00268             misc_info->setOtherCapability (conflicting_cap);
00269             _context->addInfo (misc_info);
00270         }
00271 
00272         _XDEBUG("because: '" << conflicting_item << "'conflicts " << conflicting_cap);
00273 
00274         QueueItemUninstall_Ptr uninstall_qitem = new QueueItemUninstall (_context->pool(), conflicting_item, QueueItemUninstall::CONFLICT);
00275         uninstall_qitem->setDueToConflict ();
00276         log_info = new ResolverInfoConflictsWith (conflicting_item, _install_item,
00277                                                   conflicting_cap);
00278         uninstall_qitem->addInfo (log_info);
00279         _qil.push_front (uninstall_qitem);
00280 
00281         return true;
00282     }
00283 };
00284 
00285 //---------------------------------------------------------------------------------------
00286 
00287 bool
00288 QueueItemInstall::process (ResolverContext_Ptr context, QueueItemList & qil)
00289 {
00290     ResStatus status = context->getStatus(_item);
00291 
00292     _XDEBUG( "QueueItemInstall::process(" << *this << "):" << status);
00293 
00294     /* If we are trying to upgrade item A with item B and they both have the
00295         same version number, do nothing.  This shouldn't happen in general with
00296         zypp, but can come up with the installer & autopull. */
00297 
00298     if (_upgrades
00299         && compareByNVRA(_item.resolvable(), _upgrades.resolvable()) == 0)
00300     {
00301         if (_item->kind() == ResTraits<Package>::kind) {
00302             ResolverInfo_Ptr info;
00303             _DEBUG("install of " << _item << " upgrades itself, skipping");
00304 
00305             info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_SKIPPING, _item, RESOLVER_INFO_PRIORITY_VERBOSE);
00306             context->addInfo (info);
00307             goto finished;
00308         }
00309         else {
00310             _DEBUG("re-install " << _item);
00311         }
00312     }
00313 
00314     // check if this install is still needed
00315     //   (maybe other resolver processing made this install obsolete
00316 
00317     if (!_needed_by.empty()) {
00318         bool still_needed = false;
00319 
00320         _XDEBUG( "still needed ");
00321 
00322         for (PoolItemList::const_iterator iter = _needed_by.begin(); iter != _needed_by.end() && !still_needed; ++iter) {
00323             ResStatus status = iter->status();
00324             _XDEBUG("by: [status: " << status << "] " << *iter);
00325             if (! status.isToBeUninstalled()
00326                 && ! status.isImpossible())
00327             {
00328                 still_needed = true;
00329             }
00330         }
00331 
00332         if (! still_needed)
00333             goto finished;
00334     }
00335 
00336     /* If we are in verify mode and this install is about to fail, don't let it happen...
00337            instead, we try to back out of the install by removing whatever it was that
00338            needed this. */
00339 
00340     if (context->verifying()
00341         && (status.isToBeUninstalled() || status.isImpossible())
00342         && !_needed_by.empty()) {
00343 
00344         QueueItemUninstall_Ptr uninstall_item;
00345 
00346         for (PoolItemList::const_iterator iter = _needed_by.begin(); iter != _needed_by.end(); iter++) {
00347             uninstall_item = new QueueItemUninstall (pool(), *iter, QueueItemUninstall::BACKOUT);
00348             qil.push_front (uninstall_item);
00349         }
00350 
00351         goto finished;
00352     }
00353 
00354     // If this install is due to a needed, convert it to a normal install
00355 
00356     if (status.isNeeded()) {
00357         context->setStatus (_item, _soft ? ResStatus::toBeInstalledSoft :  ResStatus::toBeInstalled);
00358     }
00359 
00360 
00361     // if this install upgrades an installed resolvable, explicitly uninstall this one
00362     //   in order to ensure that all dependencies are still met after the upgrade
00363 
00364     if (!_upgrades) {
00365 
00366         _XDEBUG("trying simple install of " <<  _item);
00367         if (!context->install (_item, context->verifying() || _soft, _other_penalty))
00368             goto finished;
00369 
00370     }
00371     else {
00372 
00373         QueueItemUninstall_Ptr uninstall_item;
00374 
00375         _XDEBUG("trying upgrade install of " << _item);
00376 
00377         if (!context->upgrade (_item, _upgrades, context->verifying() || _soft, _other_penalty)) {
00378             // invalid solution
00379             ResolverInfo_Ptr info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_INVALID_SOLUTION, PoolItem_Ref(), RESOLVER_INFO_PRIORITY_VERBOSE);
00380             context->addError (info);
00381             goto finished;
00382         }
00383 
00384         // the upgrade will uninstall the installed one, take care of this
00385 
00386         uninstall_item = new QueueItemUninstall (pool(), _upgrades, QueueItemUninstall::UPGRADE );
00387         uninstall_item->setUpgradedTo (_item);
00388 
00389         if (_explicitly_requested)
00390             uninstall_item->setExplicitlyRequested ();
00391 
00392         qil.push_front (uninstall_item);
00393 
00394     }
00395 
00396     /* Log which item need this install */
00397 
00398     if (!_needed_by.empty()) {
00399 
00400         ResolverInfoNeededBy_Ptr info;
00401 
00402         info = new ResolverInfoNeededBy (_item);
00403         info->addRelatedPoolItemList (_needed_by);
00404         context->addInfo (info);
00405     }
00406 
00407     // we're done if this isn't currently uninstalled or incomplete
00408 
00409     if (! (status.staysUninstalled()
00410            || status.isToBeUninstalledDueToUnlink()
00411            || status.isIncomplete()
00412            || status.isSatisfied()))
00413     {
00414         _XDEBUG("status " << status << " -> finished");
00415         goto finished;
00416     }
00417 
00418     _XDEBUG("status " << status << " -> NOT finished");
00419     {   // just a block for local initializers, the goto above makes this necessary
00420 
00421         ResolverInfoMisc_Ptr misc_info;
00422 
00423         if (_upgrades) {
00424 
00425             misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_UPDATING, _item, RESOLVER_INFO_PRIORITY_VERBOSE);
00426             misc_info->setOtherPoolItem (_upgrades);
00427 
00428         } else {
00429 
00430             misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_INSTALLING, _item, RESOLVER_INFO_PRIORITY_VERBOSE);
00431 
00432         }
00433 
00434         context->addInfo (misc_info);
00435         logInfo (context);
00436 
00437         /* Construct require items for each of the item's requires that is still unsatisfied. */
00438 
00439         CapSet caps;
00440 
00441         caps = _item->dep (Dep::REQUIRES);
00442 
00443         for (CapSet::const_iterator iter = caps.begin(); iter != caps.end(); iter++) {
00444 
00445             const Capability cap = *iter;
00446             _XDEBUG("this requires " << cap);
00447             bool fulfilled = false;
00448            
00449             if (_item->kind() != ResTraits<Package>::kind
00450                 || _item->kind() != ResTraits<Script>::kind
00451                 || _item->kind() != ResTraits<Message>::kind)
00452             {
00453                 bool unneeded, installed;
00454                 fulfilled = context->requirementIsMet (cap, false,
00455                                                        &unneeded, &installed);
00456                 if (!fulfilled
00457                     || (!unneeded
00458                         && !installed)) {
00459                     fulfilled = false;
00460                     _XDEBUG("Requirement is not unneeded and not installed.");              
00461                     // "low" level resolvables will be installed if they are not unneeded
00462                     // Bug 192535/204913
00463                 }
00464             }else {
00465                 fulfilled = context->requirementIsMet (cap);
00466             }
00467 
00468             if (!fulfilled) {
00469                 _XDEBUG("this requirement is still unfulfilled");
00470                 QueueItemRequire_Ptr req_item = new QueueItemRequire (pool(), cap );
00471                 req_item->addPoolItem (_item);
00472                 qil.push_front (req_item);
00473             }
00474 
00475         }
00476 
00477         caps = _item->dep (Dep::RECOMMENDS);
00478 
00479         for (CapSet::const_iterator iter = caps.begin(); iter != caps.end(); iter++) {
00480 
00481             const Capability cap = *iter;
00482             _XDEBUG("this recommends " << cap);
00483 
00484             if (!context->requirementIsMet (cap)) {
00485                 _XDEBUG("this recommends is still unfulfilled");
00486                 QueueItemRequire_Ptr req_item = new QueueItemRequire (pool(), cap, true);       // this is a soft requires
00487                 req_item->addPoolItem (_item);
00488                 qil.push_front (req_item);
00489             }
00490 
00491         }
00492 
00493         /* Construct conflict items for each of the item's conflicts. */
00494 
00495         caps = _item->dep (Dep::CONFLICTS);
00496         for (CapSet::const_iterator iter = caps.begin(); iter != caps.end(); iter++) {
00497             const Capability cap = *iter;
00498             _XDEBUG("this conflicts with '" << cap << "'");
00499             QueueItemConflict_Ptr conflict_item = new QueueItemConflict (pool(), cap, _item );
00500             // Push the QueueItem at the END of the list in order to favourite conflicts caused
00501             // by obsolating this item.
00502             qil.push_back (conflict_item);
00503         }
00504 
00505         /* Construct conflict items for each of the item's obsoletes. */
00506 
00507         caps = _item->dep (Dep::OBSOLETES);
00508         IgnoreMap ignoreMap = context->getIgnoreObsoletes();
00509         
00510         for (CapSet::const_iterator iter = caps.begin(); iter != caps.end(); iter++) {
00511             const Capability cap = *iter;
00512             bool found = false;
00513             for (IgnoreMap::iterator it = ignoreMap.begin();
00514                  it != ignoreMap.end(); it++) {
00515                 if (it->first == _item
00516                     && it->second == cap) {
00517                     _XDEBUG("Found ignoring obsoletes " << cap << " for " << _item);
00518                     found = true;
00519                     break;
00520                 }
00521             }
00522             if (!found) {           
00523                 _XDEBUG("this obsoletes " <<  cap);
00524                 QueueItemConflict_Ptr conflict_item = new QueueItemConflict (pool(), cap, _item );
00525                 conflict_item->setActuallyAnObsolete();
00526                 // Push the QueueItem at the BEGIN of the list in order to favourite this confict
00527                 // comparing to "normal" conflicts, cause this item will be deleted. So other
00528                 // conflicts will not be regarded in the future.
00529                 qil.push_front (conflict_item);
00530             }
00531         }
00532 
00533         // Go over each provides of the to-be-uninstalled item and
00534         // - re-establish any freshens
00535         // - re-establish any supplements
00536         // - find items that conflict with us and try to uninstall it if it is useful
00537 
00538         InstallEstablishItem establish;
00539 
00540         caps = _item->dep (Dep::PROVIDES);
00541         bool ignored = false;
00542 
00543         for (CapSet::const_iterator iter = caps.begin(); iter != caps.end(); iter++) {
00544             const Capability cap = *iter;
00545 
00546             /* Construct establish items for each of those which
00547                 freshen or supplement and provides of this resolvable. */
00548 
00549             _XDEBUG("Re-establish all freshens on " << cap);
00550             // pool ()->foreachFresheningResItem (cap, establish_freshens_cb, &info);
00551 
00552             Dep dep( Dep::FRESHENS);
00553             invokeOnEach( pool().byCapabilityIndexBegin( cap.index(), dep ), // begin()
00554                           pool().byCapabilityIndexEnd( cap.index(), dep ),   // end()
00555                           resfilter::ByCapMatch( cap ),
00556                           functor::functorRef<bool,CapAndItem>( establish ) );
00557 
00558             dep = Dep::SUPPLEMENTS;
00559             invokeOnEach( pool().byCapabilityIndexBegin( cap.index(), dep ), // begin()
00560                           pool().byCapabilityIndexEnd( cap.index(), dep ),   // end()
00561                           resfilter::ByCapMatch( cap ),
00562                           functor::functorRef<bool,CapAndItem>( establish ) );
00563 
00564             if (!ignored) {
00565                 // Search items that conflict with us and try to uninstall it if it is useful
00566 
00567                 UninstallConflicting info( context, cap, _item, _upgrades, qil );
00568 
00569                 Dep dep( Dep::CONFLICTS );
00570                 invokeOnEach( pool().byCapabilityIndexBegin( cap.index(), dep ),
00571                               pool().byCapabilityIndexEnd( cap.index(), dep ),
00572                               resfilter::ByCapMatch( cap ),
00573                               functor::functorRef<bool,CapAndItem>( info ) );
00574 
00575                 ignored = info.ignored;         // user choose to ignore these conflitcs
00576             }
00577 
00578         } // iterate over all provides
00579 
00580         // schedule all collected items for establish
00581 
00582         for (EstablishMap::iterator it = establish.establishmap.begin(); it != establish.establishmap.end(); ++it) {
00583             QueueItemEstablish_Ptr establish_item = new QueueItemEstablish (pool(), it->second, true);
00584             qil.push_front( establish_item );
00585         }
00586 
00587     } // end of goto-over-definitions-to-finished block
00588 
00589  finished:
00590 
00591     return true;
00592 }
00593 
00594 
00595 QueueItem_Ptr
00596 QueueItemInstall::copy (void) const
00597 {
00598     QueueItemInstall_Ptr new_install = new QueueItemInstall (pool(), _item);
00599     new_install->QueueItem::copy(this);
00600 
00601     new_install->_upgrades = _upgrades;
00602     new_install->_deps_satisfied_by_this_install = CapSet(_deps_satisfied_by_this_install.begin(), _deps_satisfied_by_this_install.end());
00603     new_install->_needed_by = PoolItemList (_needed_by.begin(), _needed_by.end());
00604     new_install->_channel_priority = _channel_priority;
00605     new_install->_other_penalty = _other_penalty;
00606     new_install->_explicitly_requested = _explicitly_requested;
00607 
00608     return new_install;
00609 }
00610 
00611 
00612 int
00613 QueueItemInstall::cmp (QueueItem_constPtr item) const
00614 {
00615     int cmp = this->compare (item);
00616     if (cmp != 0)
00617         return cmp;
00618     QueueItemInstall_constPtr install = dynamic_pointer_cast<const QueueItemInstall>(item);
00619     return compareByNVRA (_item.resolvable(), install->_item.resolvable());
00620 }
00621 
00622 //---------------------------------------------------------------------------
00623 
00624 void
00625 QueueItemInstall::addDependency (const Capability & dep)
00626 {
00627     _deps_satisfied_by_this_install.insert (dep);
00628 }
00629 
00630 
00631 void
00632 QueueItemInstall::addNeededBy (PoolItem_Ref item)
00633 {
00634     _needed_by.push_front (item);
00635 }
00636 
00638     };// namespace detail
00641   };// namespace solver
00644 };// namespace zypp
00646 

Generated on Wed Sep 27 01:16:39 2006 for zypp by  doxygen 1.4.6