00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "zypp/solver/detail/Helper.h"
00025
00026 #include "zypp/CapSet.h"
00027 #include "zypp/base/Logger.h"
00028 #include "zypp/base/String.h"
00029 #include "zypp/base/Gettext.h"
00030 #include "zypp/VendorAttr.h"
00031 #include "zypp/base/Algorithm.h"
00032 #include "zypp/ResPool.h"
00033 #include "zypp/ResFilters.h"
00034 #include "zypp/CapFilters.h"
00035
00036 using namespace std;
00037
00039 namespace zypp
00040 {
00041
00042 namespace solver
00043 {
00044
00045 namespace detail
00046 {
00047
00048 ostream &
00049 operator<< (ostream & os, const PoolItemList & itemlist)
00050 {
00051 for (PoolItemList::const_iterator iter = itemlist.begin(); iter != itemlist.end(); ++iter) {
00052 if (iter != itemlist.begin())
00053 os << ", ";
00054 os << *iter;
00055 }
00056 return os;
00057 }
00058
00059
00060 class LookFor : public resfilter::PoolItemFilterFunctor
00061 {
00062 public:
00063 PoolItem_Ref item;
00064
00065 bool operator()( PoolItem_Ref provider )
00066 {
00067 item = provider;
00068 return false;
00069 }
00070 };
00071
00072
00073
00074
00075 PoolItem_Ref
00076 Helper::findInstalledByNameAndKind (const ResPool & pool, const string & name, const Resolvable::Kind & kind)
00077 {
00078 LookFor info;
00079
00080 invokeOnEach( pool.byNameBegin( name ),
00081 pool.byNameEnd( name ),
00082 functor::chain (resfilter::ByInstalled (),
00083 resfilter::ByKind( kind ) ),
00084 functor::functorRef<bool,PoolItem> (info) );
00085
00086 _XDEBUG("Helper::findInstalledByNameAndKind (" << name << ", " << kind << ") => " << info.item);
00087 return info.item;
00088 }
00089
00090
00091
00092
00093 PoolItem_Ref
00094 Helper::findUninstalledByNameAndKind (const ResPool & pool, const string & name, const Resolvable::Kind & kind)
00095 {
00096 LookFor info;
00097
00098 invokeOnEach( pool.byNameBegin( name ),
00099 pool.byNameEnd( name ),
00100 functor::chain (resfilter::ByUninstalled (),
00101 resfilter::ByKind( kind ) ),
00102 functor::functorRef<bool,PoolItem> (info) );
00103
00104 _XDEBUG("Helper::findUninstalledByNameAndKind (" << name << ", " << kind << ") => " << info.item);
00105 return info.item;
00106 }
00107
00108
00109
00110
00111
00112 PoolItem_Ref
00113 Helper::findInstalledItem (const ResPool & pool, PoolItem_Ref item)
00114 {
00115 return findInstalledByNameAndKind (pool, item->name(), item->kind() );
00116 }
00117
00118
00119
00120 class LookForUpdate : public resfilter::PoolItemFilterFunctor
00121 {
00122 public:
00123 PoolItem_Ref uninstalled;
00124 PoolItem_Ref installed;
00125
00126 bool operator()( PoolItem_Ref provider )
00127 {
00128
00129 if ( ! provider.resolvable() )
00130 {
00131 WAR << "Warning: '" << provider << "' not valid" << endl;
00132 return true;
00133 }
00134
00135 if ( installed.resolvable() )
00136 {
00137 if ( !VendorAttr::instance().equivalent(installed->vendor(),provider->vendor()) )
00138 {
00139 MIL << "Discarding '" << provider << "' from vendor '"
00140 << provider->vendor() << "' different to uninstalled '"
00141 << installed->vendor() << "' vendor." << endl;
00142 return true;
00143 }
00144 }
00145
00146 if ((!uninstalled
00147 || (uninstalled->edition().compare( provider->edition() ) < 0)
00148 || (uninstalled->arch().compare( provider->arch() ) < 0) )
00149 && !provider.status().isLocked() )
00150 {
00151 uninstalled = provider;
00152 }
00153 return true;
00154 }
00155 };
00156
00157
00158
00159
00160
00161 PoolItem_Ref
00162 Helper::findUpdateItem (const ResPool & pool, PoolItem_Ref item)
00163 {
00164 LookForUpdate info;
00165 info.installed = item;
00166
00167 invokeOnEach( pool.byNameBegin( item->name() ),
00168 pool.byNameEnd( item->name() ),
00169 functor::chain (functor::chain (resfilter::ByUninstalled (),
00170 resfilter::ByKind( item->kind() ) ),
00171 resfilter::byEdition<CompareByGT<Edition> >( item->edition() )),
00172 functor::functorRef<bool,PoolItem> (info) );
00173
00174 _XDEBUG("Helper::findUpdateItem(" << item << ") => " << info.uninstalled);
00175 return info.uninstalled;
00176 }
00177
00178
00179
00180
00181 class LookForReinstall : public resfilter::PoolItemFilterFunctor
00182 {
00183 public:
00184 PoolItem_Ref uninstalled;
00185
00186 bool operator()( PoolItem_Ref provider )
00187 {
00188 if (provider.status().isLocked()) {
00189 return true;
00190 } else {
00191 uninstalled = provider;
00192 return false;
00193 }
00194 }
00195 };
00196
00197
00198 PoolItem_Ref
00199 Helper::findReinstallItem (const ResPool & pool, PoolItem_Ref item)
00200 {
00201 LookForReinstall info;
00202
00203 invokeOnEach( pool.byNameBegin( item->name() ),
00204 pool.byNameEnd( item->name() ),
00205 functor::chain (functor::chain (resfilter::ByUninstalled (),
00206 resfilter::ByKind( item->kind() ) ),
00207 resfilter::byEdition<CompareByEQ<Edition> >( item->edition() )),
00208 functor::functorRef<bool,PoolItem> (info) );
00209
00210 _XDEBUG("Helper::findReinstallItem(" << item << ") => " << info.uninstalled);
00211 return info.uninstalled;
00212 }
00213
00214
00215
00216 class CheckIfBest : public resfilter::PoolItemFilterFunctor
00217 {
00218 public:
00219 PoolItem_Ref _item;
00220 bool is_best;
00221
00222 CheckIfBest( PoolItem_Ref item )
00223 : _item( item )
00224 , is_best( true )
00225 {}
00226
00227
00228
00229 bool operator()( PoolItem_Ref provider )
00230 {
00231 int archcmp = _item->arch().compare( provider->arch() );
00232 if (((archcmp < 0)
00233 || ((archcmp == 0)
00234 && (_item->edition().compare( provider->edition() ) < 0)))
00235 && !provider.status().isLocked())
00236 {
00237 is_best = false;
00238 return false;
00239 }
00240 return true;
00241 }
00242 };
00243
00244
00245
00246
00247 bool
00248 Helper::isBestUninstalledItem (const ResPool & pool, PoolItem_Ref item)
00249 {
00250 CheckIfBest info( item );
00251
00252 invokeOnEach( pool.byNameBegin( item->name() ),
00253 pool.byNameEnd( item->name() ),
00254 functor::chain( resfilter::ByUninstalled(),
00255 resfilter::ByKind( item->kind() ) ),
00256 functor::functorRef<bool,PoolItem>( info ) );
00257
00258 _XDEBUG("Helper::isBestUninstalledItem(" << item << ") => " << info.is_best);
00259 return info.is_best;
00260 }
00261
00262
00264 };
00267 };
00270 };
00272