- Take into account the requirements of all obsoleted packages uninstall
[platform/upstream/libzypp.git] / zypp / solver / detail / InstallOrder.cc
index 4cbdbba..68925f2 100644 (file)
 #include "zypp/base/Iterator.h"
 #include "zypp/base/Algorithm.h"
 
+#include "zypp/solver/detail/SATResolver.h"
+
 #include "zypp/ResFilters.h"
 #include "zypp/ResStatus.h"
-#include "zypp/CapAndItem.h"
 #include "zypp/NameKindProxy.h"
+#include "zypp/sat/Pool.h"
+#include <zypp/sat/WhatObsoletes.h>
 
 /////////////////////////////////////////////////////////////////////////
 namespace zypp
@@ -175,37 +178,6 @@ InstallOrder::findProviderInSet( const Capability requirement, const PoolItemSet
     return PoolItem();
 }
 
-struct CollectProviders
-{
-    const PoolItem requestor;
-    PoolItemList result;
-    const PoolItemSet & limitto;               // limit search to members of this set
-
-    CollectProviders (const PoolItem pi, const PoolItemSet & limit)
-       : requestor (pi)
-       , limitto (limit)
-    { }
-
-
-    bool operator()( const CapAndItem & c_and_i )
-    {
-       // item provides cap which matches a requirement from info->requestor
-       //   this function gets _all_ providers and filter out those which are
-       //   either installed or in our toinstall input list
-       //
-XXX << "info(" << c_and_i.item <<")"<< endl;
-       if ((c_and_i.item.resolvable() != requestor.resolvable())       // resolvable could provide its own requirement
-           && (limitto.find( c_and_i.item ) != limitto.end()))         // limit to members of 'limitto' set
-       {
-           XXX << "tovisit " << ITEMNAME(c_and_i.item) << endl;
-           result.push_back (c_and_i.item);
-       }
-
-       return true;
-    }
-
-};
-
 //-----------------------------------------------------------------------------
 
 
@@ -225,12 +197,12 @@ InstallOrder::rdfsvisit (const PoolItem item)
 
     // items prereq
     CapabilitySet prq( item->dep(Dep::PREREQUIRES).begin(), item->dep(Dep::PREREQUIRES).end() );
-    // an installed items prereq (in case they are reqired for uninstall scripts)
-    NameKindProxy nkp( _pool, item->name(), item->kind() );
-    if ( ! nkp.installedEmpty() )
+    // any obsoleted items prereq (in case they are reqired for uninstall scripts)
+    sat::WhatObsoletes obs( item );
+    for_( it, obs.begin(), obs.end() )
     {
-      prq.insert( (*nkp.installedBegin())->dep(Dep::PREREQUIRES).begin(),
-                 (*nkp.installedBegin())->dep(Dep::PREREQUIRES).end() );
+      Capabilities p( it->prerequires() );
+      prq.insert( p.begin(), p.end() );
     }
     // put prerequires first and requires last on list to ensure
     // that prerequires are processed first
@@ -251,32 +223,45 @@ InstallOrder::rdfsvisit (const PoolItem item)
 
     for (CapList::const_iterator iter = requires.begin(); iter != requires.end(); ++iter)
     {
+        bool goBack = false;
        const Capability requirement = *iter;
+        PoolItemList providers;
+
        XXX << "check requirement " << requirement << " of " << ITEMNAME(item) << endl;
+        SATResolver satResolver(_pool, sat::Pool::instance().get());
        PoolItemList tovisit;
-
-       // _world->foreachProvidingResItem (requirement, collect_providers, &info);
-       Dep dep (Dep::PROVIDES);
+        sat::WhatProvides possibleProviders(requirement);
 
        // first, look in _installed
-       CollectProviders info ( item, _installed );
-
-       invokeOnEach( _pool.byCapabilityIndexBegin( requirement.index(), dep ),
-                     _pool.byCapabilityIndexEnd( requirement.index(), dep ),
-                     resfilter::ByCapMatch( requirement ),
-                     functor::functorRef<bool,CapAndItem>(info) );
-
-       // if not found in _iustalled, look in _toinstall
-
-       if (info.result.empty()) {
-           CollectProviders info1 ( item, _toinstall );
-
-           invokeOnEach( _pool.byCapabilityIndexBegin( requirement.index(), dep ),
-                         _pool.byCapabilityIndexEnd( requirement.index(), dep ),
-                         resfilter::ByCapMatch( requirement ),
-                         functor::functorRef<bool,CapAndItem>(info1) );
-
-           tovisit = info1.result;
+        for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
+            PoolItem provider = ResPool::instance().find( *iter );
+            if ( provider == item )
+            {
+              goBack = true;
+              break;
+            }
+            if (_installed.find( provider ) != _installed.end())       // and is not installed
+            {
+                XXX << "tovisit " << ITEMNAME(provider) << endl;
+                providers.push_back (provider);
+            }
+        }
+
+        if ( goBack )
+          continue;
+
+       // if not found in _installed, look in _toinstall
+
+       if (providers.empty()) {
+            for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
+                PoolItem provider = ResPool::instance().find( *iter );
+                if ((provider.resolvable() != item.resolvable())               // resolvable could provide its own requirement
+                    && (_toinstall.find( provider ) != _toinstall.end()))      // and is not to be installed
+                {
+                    XXX << "tovisit " << ITEMNAME(provider) << endl;
+                    tovisit.push_back (provider);
+                }
+            }
        }
 
        for (PoolItemList::iterator it = tovisit.begin(); it != tovisit.end(); ++it)