[yum-commits] Branch 'yum-3_2_X' - 8 commits - test/testbase.py yum/depsolve.py yum/__init__.py yum/packageSack.py yum/packages.py yum/rpmsack.py yum/sqlitesack.py yum/transactioninfo.py

James Antill james at osuosl.org
Fri Apr 16 13:33:22 UTC 2010


 test/testbase.py       |   11 +++++++
 yum/__init__.py        |   37 +++++++++++++++--------
 yum/depsolve.py        |    6 ++-
 yum/packageSack.py     |   14 +++++++--
 yum/packages.py        |   76 +++++++++++++++++++++++++++++++++++++++++++------
 yum/rpmsack.py         |   45 +++++++++++++++++++++++++++--
 yum/sqlitesack.py      |   37 +++++++++++++++++++++++
 yum/transactioninfo.py |   12 ++++---
 8 files changed, 204 insertions(+), 34 deletions(-)

New commits:
commit f06b289b3e88cd22948f376509cd84d04263b7aa
Author: James Antill <james at and.org>
Date:   Fri Apr 16 09:32:53 2010 -0400

    Rename filterObsoleters => obsoletedBy, before it goes public

diff --git a/yum/__init__.py b/yum/__init__.py
index ab2e6d5..34f2de7 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -2876,7 +2876,7 @@ class YumBase(depsolve.Depsolve):
         else:
             for obs_n in po.obsoletes_names:
                 for pkg in self.rpmdb.searchNevra(name=obs_n):
-                    if pkg.filterObsoleters([po]):
+                    if pkg.obsoletedBy([po]):
                         yield pkg
 
     def _add_prob_flags(self, *flags):
@@ -3036,7 +3036,7 @@ class YumBase(depsolve.Depsolve):
                 # is already installed
                 already_obs = None
                 pkgs = self.rpmdb.searchNevra(name=obsoleting_pkg.name)
-                pkgs = po.filterObsoleters(pkgs, limit=1)
+                pkgs = po.obsoletedBy(pkgs, limit=1)
                 if pkgs:
                     already_obs = pkgs[0]
                     continue
diff --git a/yum/depsolve.py b/yum/depsolve.py
index e62680f..a9e4d55 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -1206,7 +1206,7 @@ class Depsolve(object):
                     pkgresults[po] -= 1024
 
                 obsoleted = False
-                if po.filterObsoleters([nextpo]):
+                if po.obsoletedBy([nextpo]):
                     obsoleted = True
                     pkgresults[po] -= 1024
                                 
diff --git a/yum/packages.py b/yum/packages.py
index 6108636..e01790c 100644
--- a/yum/packages.py
+++ b/yum/packages.py
@@ -596,7 +596,7 @@ class RpmBase(object):
             using searchFiles(). """
         return self.repo.sack.have_fastReturnFileEntries()
 
-    def filterObsoleters(self, obsoleters, limit=0):
+    def obsoletedBy(self, obsoleters, limit=0):
         """ Returns list of obsoleters that obsolete this package. Note that we
             don't do obsoleting loops. If limit is != 0, then we stop after
             finding that many. """
diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index 996416b..7f5b233 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -1324,7 +1324,7 @@ class RPMDBPackageSack(PackageSackBase):
                 continue
             obsoleters.append(pkg)
         for pkg in sorted(self.returnPackages()):
-            for obspo in pkg.filterObsoleters(obsoleters):
+            for obspo in pkg.obsoletedBy(obsoleters):
                 problems.append(RPMDBProblemObsoleted(pkg, obsoleter=obspo))
         return problems
 
commit f9b8420f54162289d79e5c8b84291057758a609f
Author: James Antill <james at and.org>
Date:   Thu Apr 15 15:11:32 2010 -0400

    Add nocontexts to possible ts flag usage, when available

diff --git a/yum/depsolve.py b/yum/depsolve.py
index 8b02d7c..e62680f 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -138,6 +138,9 @@ class Depsolve(object):
                             'test': rpm.RPMTRANS_FLAG_TEST,
                             'justdb': rpm.RPMTRANS_FLAG_JUSTDB,
                             'repackage': rpm.RPMTRANS_FLAG_REPACKAGE}
+        # This is only in newer rpm.org releases
+        if hasattr(rpm, 'RPMTRANS_FLAG_NOCONTEXTS'):
+            ts_flags_to_rpm['nocontexts'] = rpm.RPMTRANS_FLAG_NOCONTEXTS
         
         self._ts.setFlags(0) # reset everything.
         
commit 94d742bf395cc565cf3a0dca138608a9296b1303
Author: James Antill <james at and.org>
Date:   Thu Apr 15 13:18:18 2010 -0400

     Add pkg.filterObsoleters(), so we don't have to create the provide
    tuple and test "backwards".
     Also convert callers.
    
     We've screwed this up a few times, by doing provides checks instead and
    this drops a few lines of code anyway ... so should be good.

diff --git a/yum/__init__.py b/yum/__init__.py
index 9e8fad9..ab2e6d5 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -2874,11 +2874,9 @@ class YumBase(depsolve.Depsolve):
                     installed_pkg =  self.getInstalledPackageObject(inst_tup)
                     yield installed_pkg
         else:
-            for (obs_n, obs_f, (obs_e, obs_v, obs_r)) in po.obsoletes:
+            for obs_n in po.obsoletes_names:
                 for pkg in self.rpmdb.searchNevra(name=obs_n):
-                    installedtup = (pkg.name, 'EQ', (pkg.epoch, 
-                                   pkg.ver, pkg.release))
-                    if po.inPrcoRange('obsoletes', installedtup):
+                    if pkg.filterObsoleters([po]):
                         yield pkg
 
     def _add_prob_flags(self, *flags):
@@ -3037,11 +3035,11 @@ class YumBase(depsolve.Depsolve):
                 # pull in foo.i586 when foo.x86_64 already obsoletes the pkg and
                 # is already installed
                 already_obs = None
-                poprovtup = (po.name, 'EQ', (po.epoch, po.ver, po.release))
-                for pkg in self.rpmdb.searchNevra(name=obsoleting_pkg.name):
-                    if pkg.inPrcoRange('obsoletes', poprovtup):
-                        already_obs = pkg
-                        continue
+                pkgs = self.rpmdb.searchNevra(name=obsoleting_pkg.name)
+                pkgs = po.filterObsoleters(pkgs, limit=1)
+                if pkgs:
+                    already_obs = pkgs[0]
+                    continue
 
                 if already_obs:
                     self.verbose_logger.warning(_('Package %s is obsoleted by %s which is already installed'), 
diff --git a/yum/depsolve.py b/yum/depsolve.py
index 48f77d5..8b02d7c 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -1203,8 +1203,7 @@ class Depsolve(object):
                     pkgresults[po] -= 1024
 
                 obsoleted = False
-                poprovtup = (po.name, 'EQ', (po.epoch, po.ver, po.release))
-                if nextpo.inPrcoRange('obsoletes', poprovtup):
+                if po.filterObsoleters([nextpo]):
                     obsoleted = True
                     pkgresults[po] -= 1024
                                 
diff --git a/yum/packages.py b/yum/packages.py
index c1a14d0..6108636 100644
--- a/yum/packages.py
+++ b/yum/packages.py
@@ -596,6 +596,20 @@ class RpmBase(object):
             using searchFiles(). """
         return self.repo.sack.have_fastReturnFileEntries()
 
+    def filterObsoleters(self, obsoleters, limit=0):
+        """ Returns list of obsoleters that obsolete this package. Note that we
+            don't do obsoleting loops. If limit is != 0, then we stop after
+            finding that many. """
+        provtup = (self.name, 'EQ', (self.epoch, self.version, self.release))
+        ret = []
+        for obspo in obsoleters:
+            if obspo.inPrcoRange('obsoletes', provtup):
+                ret.append(obspo)
+                if limit and len(ret) > limit:
+                    break
+        return ret
+
+
 
 # This is kind of deprecated
 class PackageEVR:
diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index eba1409..996416b 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -1324,10 +1324,8 @@ class RPMDBPackageSack(PackageSackBase):
                 continue
             obsoleters.append(pkg)
         for pkg in sorted(self.returnPackages()):
-            provtup = (pkg.name, 'EQ', (pkg.epoch, pkg.version, pkg.release))
-            for obspo in obsoleters:
-                if obspo.inPrcoRange('obsoletes', provtup):
-                    problems.append(RPMDBProblemObsoleted(pkg, obsoleter=obspo))
+            for obspo in pkg.filterObsoleters(obsoleters):
+                problems.append(RPMDBProblemObsoleted(pkg, obsoleter=obspo))
         return problems
 
     def check_provides(self):
commit 5f6c04f93ef6cf3272197560bb914ce5fd410155
Author: James Antill <james at and.org>
Date:   Thu Apr 15 12:54:42 2010 -0400

     Add primary_only arg. to returnFileTypes(), use it from transactioninfo
    sack so that we don't require filelists to be downloaded.

diff --git a/yum/packages.py b/yum/packages.py
index 731d217..c1a14d0 100644
--- a/yum/packages.py
+++ b/yum/packages.py
@@ -514,9 +514,26 @@ class RpmBase(object):
                 return self.files[ftype]
         return []
             
-    def returnFileTypes(self):
-        """return list of types of files in the package"""
-        # maybe should die - use direct access to attribute
+    def returnFileTypes(self, primary_only=False):
+        """return list of types of files in the package, you can pass
+           primary_only=True to limit to those files in the primary repodata"""
+        if primary_only:
+            ret = [] # We only return the types for the primary files.
+            for ftype in self.files.keys():
+                if ftype == 'dir':
+                    match = misc.re_primary_dirname
+                else:
+                    match = misc.re_primary_filename
+                #  As soon as we find a primary file of this type, we can
+                # return it.
+                for fn in self.files[ftype]:
+                    if match(fn):
+                        break
+                else:
+                    continue
+                ret.append(ftype)
+            return ret
+
         return self.files.keys()
 
     def returnPrcoNames(self, prcotype):
diff --git a/yum/sqlitesack.py b/yum/sqlitesack.py
index 1885d57..43f60cd 100644
--- a/yum/sqlitesack.py
+++ b/yum/sqlitesack.py
@@ -353,6 +353,8 @@ class YumAvailablePackageSqlite(YumAvailablePackage, PackageObject, RpmBase):
         return self._changelog
     
     def returnFileEntries(self, ftype='file', primary_only=False):
+        """return list of files based on type, you can pass primary_only=True
+           to limit to those files in the primary repodata"""
         if primary_only and not self._loadedfiles:
             sql = "SELECT name as fname FROM files WHERE pkgKey = ? and type = ?"
             cur = self._sql_MD('primary', sql, (self.pkgKey, ftype))
@@ -361,7 +363,14 @@ class YumAvailablePackageSqlite(YumAvailablePackage, PackageObject, RpmBase):
         self._loadFiles()
         return RpmBase.returnFileEntries(self,ftype,primary_only)
     
-    def returnFileTypes(self):
+    def returnFileTypes(self, primary_only=False):
+        """return list of types of files in the package, you can pass
+           primary_only=True to limit to those files in the primary repodata"""
+        if primary_only and not self._loadedfiles:
+            sql = "SELECT DISTINCT type as ftype FROM files WHERE pkgKey = ?"
+            cur = self._sql_MD('primary', sql, (self.pkgKey,))
+            return map(lambda x: x['ftype'], cur)
+
         self._loadFiles()
         return RpmBase.returnFileTypes(self)
 
diff --git a/yum/transactioninfo.py b/yum/transactioninfo.py
index d7d8859..dfa34b3 100644
--- a/yum/transactioninfo.py
+++ b/yum/transactioninfo.py
@@ -39,7 +39,7 @@ class GetProvReqOnlyPackageSack(PackageSack):
         self._need_index_files = need_files
 
     def __addPackageToIndex_primary_files(self, obj):
-        for ftype in obj.returnFileTypes():
+        for ftype in obj.returnFileTypes(primary_only=True):
             for file in obj.returnFileEntries(ftype, primary_only=True):
                 self._addToDictAsList(self.filenames, file, obj)
     def __addPackageToIndex_files(self, obj):
commit e8ce2ff4619b69d8ad244a5df5aeaf484076203b
Author: James Antill <james at and.org>
Date:   Thu Apr 15 12:37:51 2010 -0400

     Fix the docs. for have_fast*
    
     Rename it from have_fastSearchFiles to have_fastReturnFileEntries to
    better reflect what it means.
     Add a dummy to PO, as that's the logical place for it even though it
    needs to be in the sack for sqlite to get the answer.
    
     Add some docs. to the package object classes, while we are here.

diff --git a/test/testbase.py b/test/testbase.py
index 44d1959..fa2e512 100644
--- a/test/testbase.py
+++ b/test/testbase.py
@@ -51,7 +51,7 @@ class FakeSack:
     def __init__(self):
         pass # This is fake, so do nothing
     
-    def have_fastSearchFiles(self):
+    def have_fastReturnFileEntries(self):
         return True
 
 class FakeRepo(object):
diff --git a/yum/__init__.py b/yum/__init__.py
index cc5064e..9e8fad9 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -4409,7 +4409,7 @@ class YumBase(depsolve.Depsolve):
         
         if pkg1.name != pkg2.name:
             return False
-        if not pkg1.EVR  > pkg2.EVR:
+        if pkg1.verLE(pkg2):
             return False
         if pkg1.arch not in self.arch.archlist:
             return False
diff --git a/yum/packageSack.py b/yum/packageSack.py
index e63a8d7..dbe54bf 100644
--- a/yum/packageSack.py
+++ b/yum/packageSack.py
@@ -152,8 +152,9 @@ class PackageSackBase(object):
         """returns a dict of obsoletes dict[obsoleting pkgtuple] = [list of obs]"""
         raise NotImplementedError()
 
-    def have_fastSearchFiles(self):
-        """ Is calling searchFiles() faster than using """
+    def have_fastReturnFileEntries(self):
+        """ Is calling pkg.returnFileEntries(primary_only=True) faster than
+            using searchFiles(). """
         raise NotImplementedError()
 
     def searchFiles(self, name):
@@ -776,7 +777,9 @@ class PackageSack(PackageSackBase):
             
         return obs
         
-    def have_fastSearchFiles(self):
+    def have_fastReturnFileEntries(self):
+        """ Is calling pkg.returnFileEntries(primary_only=True) faster than
+            using searchFiles(). """
         return True
 
     def searchFiles(self, name):
diff --git a/yum/packages.py b/yum/packages.py
index 289660d..731d217 100644
--- a/yum/packages.py
+++ b/yum/packages.py
@@ -159,7 +159,9 @@ class FakeSack:
     def __init__(self):
         pass # This is fake, so do nothing
     
-    def have_fastSearchFiles(self):
+    def have_fastReturnFileEntries(self):
+        """ Is calling pkg.returnFileEntries(primary_only=True) faster than
+            using searchFiles(). """
         return True
 
     def delPackage(self, obj):
@@ -213,8 +215,10 @@ class FakeRepository:
         return self.id
 
 
-# goal for the below is to have a packageobject that can be used by generic
+#  Goal for the below is to have a packageobject that can be used by generic
 # functions independent of the type of package - ie: installed or available
+#  Note that this is also used to history etc. ... so it's more a nevra+checksum
+# holder than a base for things which are actual packages.
 class PackageObject(object):
     """Base Package Object - sets up the default storage dicts and the
        most common returns"""
@@ -299,11 +303,16 @@ class PackageObject(object):
     def verEQ(self, other):
         """ Compare package to another one, only rpm-version equality. """
         if not other:
-            return False
+            return None
         ret = cmp(self.name, other.name)
         if ret != 0:
             return False
         return comparePoEVREQ(self, other)
+    def verNE(self, other):
+        """ Compare package to another one, only rpm-version inequality. """
+        if not other:
+            return None
+        return not self.verEQ(other)
     def verLT(self, other):
         """ Uses verCMP, tests if the other _rpm-version_ is <  ours. """
         return self.verCMP(other) <  0
@@ -335,6 +344,10 @@ class PackageObject(object):
             if csumid:
                 return (csumtype, csum)
 
+#  This is the virtual base class of actual packages, it basically requires a
+# repo. even though it doesn't set one up in it's __init__. It also doesn't have
+# PackageObject methods ... so is basically unusable on it's own
+# see: YumAvailablePackage.
 class RpmBase(object):
     """return functions and storage for rpm-specific data"""
 
@@ -561,11 +574,18 @@ class RpmBase(object):
 
     base_package_name = property(fget=lambda self: self._getBaseName())
 
+    def have_fastReturnFileEntries(self):
+        """ Is calling pkg.returnFileEntries(primary_only=True) faster than
+            using searchFiles(). """
+        return self.repo.sack.have_fastReturnFileEntries()
 
+
+# This is kind of deprecated
 class PackageEVR:
 
     """
-    A comparable epoch, version, and release representation.
+    A comparable epoch, version, and release representation. Note that you
+    almost certainly want to use pkg.verEQ() or pkg.verGT() etc. instead.
     """
     
     def __init__(self,e,v,r):
@@ -608,7 +628,8 @@ class PackageEVR:
         return False
     
 
-
+#  This is the real base class of actual packages, it has a repo. and is
+# usable on it's own, in theory (but in practise see sqlitesack).
 class YumAvailablePackage(PackageObject, RpmBase):
     """derived class for the  packageobject and RpmBase packageobject yum
        uses this for dealing with packages in a repository"""
@@ -1124,7 +1145,8 @@ class YumAvailablePackage(PackageObject, RpmBase):
 
 
 
-
+#  This is a tweak on YumAvailablePackage() and is a base class for packages
+# which are actual rpms.
 class YumHeaderPackage(YumAvailablePackage):
     """Package object built from an rpm header"""
     def __init__(self, repo, hdr):
@@ -1364,6 +1386,7 @@ _RPMVERIFY_RDEV     = (1 << 7)
 
 _installed_repo = FakeRepository('installed')
 _installed_repo.cost = 0
+# This is a tweak on YumHeaderPackage() for installed rpm packages.
 class YumInstalledPackage(YumHeaderPackage):
     """super class for dealing with packages in the rpmdb"""
     def __init__(self, hdr, yumdb=None):
@@ -1627,6 +1650,7 @@ class YumInstalledPackage(YumHeaderPackage):
         return results
         
                              
+# This is a tweak on YumHeaderPackage() for rpm packages which are on disk.
 class YumLocalPackage(YumHeaderPackage):
     """Class to handle an arbitrary package from a file path
        this inherits most things from YumInstalledPackage because
@@ -1770,6 +1794,8 @@ class YumLocalPackage(YumHeaderPackage):
         return msg
 
 
+#  This is a tweak on YumLocalPackage() to download rpm packages to disk, and
+# then use them directly.
 class YumUrlPackage(YumLocalPackage):
     """Class to handle an arbitrary package from a URL
        this inherits most things from YumLocalPackage, but will download a
diff --git a/yum/sqlitesack.py b/yum/sqlitesack.py
index 74c793a..1885d57 100644
--- a/yum/sqlitesack.py
+++ b/yum/sqlitesack.py
@@ -842,9 +842,9 @@ class YumSqlitePackageSack(yumRepo.YumPackageSack):
         return misc.unique(results)
         
     @catchSqliteException
-    def _have_fastSearchFiles(self):
-        """ Return true if searchFiles() is always fast, basically relies on
-            "CREATE INDEX pkgfiles ON files (pkgKey);" existing. """
+    def _have_fastReturnFileEntries(self):
+        """ Return true if pkg.returnFileEntries(primary_only=True) is fast.
+            basically does "CREATE INDEX pkgfiles ON files (pkgKey);" exist. """
 
         for (rep,cache) in self.primarydb.items():
             if rep in self._all_excludes:
@@ -860,10 +860,12 @@ class YumSqlitePackageSack(yumRepo.YumPackageSack):
 
         return True
 
-    def have_fastSearchFiles(self):
-        if not hasattr(self, '_cached_have_fastSearchFiles'):
-            self._cached_have_fastSearchFiles = self._have_fastSearchFiles()
-        return self._cached_have_fastSearchFiles
+    def have_fastReturnFileEntries(self):
+        """ Is calling pkg.returnFileEntries(primary_only=True) faster than
+            using searchFiles(). """
+        if not hasattr(self, '_cached_fRFE'):
+            self._cached_fRFE = self._have_fastReturnFileEntries()
+        return self._cached_fRFE
 
     @catchSqliteException
     def searchFiles(self, name, strict=False):
diff --git a/yum/transactioninfo.py b/yum/transactioninfo.py
index cad36f4..d7d8859 100644
--- a/yum/transactioninfo.py
+++ b/yum/transactioninfo.py
@@ -237,7 +237,7 @@ class TransactionData:
         elif isinstance(txmember.po, YumAvailablePackageSqlite):
             self.pkgSackPackages += 1
         if self._inSack is not None and txmember.output_state in TS_INSTALL_STATES:
-            if not txmember.po.repo.sack.have_fastSearchFiles():
+            if not txmember.po.have_fastReturnFileEntries():
                 # In theory we could keep this on if a "small" repo. fails
                 self._inSack = None
             else:
commit 1f714fa2f00b1d92fc5636e58cf9ad97fd638b03
Author: James Antill <james at and.org>
Date:   Thu Apr 15 01:33:32 2010 -0400

    Fix rpmdb.searchPrco() with "globs", can also affect getProvides() etc.

diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index e18df3f..eba1409 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -322,8 +322,8 @@ class RPMDBPackageSack(PackageSackBase):
             if not glob:
                 if po.checkPrco(prcotype, (n, f, (e,v,r))):
                     result[po.pkgid] = po
-                else:
-                    result[po.pkgid] = po
+            else:
+                result[po.pkgid] = po
         del mi
 
 
commit 204a4d086e601cf4517cf39e23eaad49ac71eedf
Author: James Antill <james at and.org>
Date:   Thu Apr 15 01:32:19 2010 -0400

    Add obsoleted and provides index checking, don't default to doing them though

diff --git a/yum/__init__.py b/yum/__init__.py
index 35da86e..cc5064e 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -1139,9 +1139,11 @@ class YumBase(depsolve.Depsolve):
             toRemove.add(dep)
             self._getDepsToRemove(dep, deptree, toRemove)
 
-    def _rpmdb_warn_checks(self, out=None, warn=True, chkcmd='all',header=None):
+    def _rpmdb_warn_checks(self, out=None, warn=True, chkcmd=None, header=None):
         if out is None:
             out = self.logger.warning
+        if chkcmd is None:
+            chkcmd = ['dependencies', 'duplicates']
         if header is None:
             # FIXME: _N()
             msg = _("** Found %d pre-existing rpmdb problem(s),"
@@ -1150,17 +1152,28 @@ class YumBase(depsolve.Depsolve):
         if warn:
             out(_('Warning: RPMDB altered outside of yum.'))
 
+        if type(chkcmd) in (type([]), type(set())):
+            chkcmd = set(chkcmd)
+        else:
+            chkcmd = set([chkcmd])
+
         rc = 0
         probs = []
-        if chkcmd in ('all', 'dependencies'):
+        if chkcmd.intersection(set(('all', 'dependencies'))):
             prob2ui = {'requires' : _('missing requires'),
                        'conflicts' : _('installed conflict')}
             probs.extend(self.rpmdb.check_dependencies())
 
-        if chkcmd in ('all', 'duplicates'):
+        if chkcmd.intersection(set(('all', 'duplicates'))):
             iopkgs = set(self.conf.installonlypkgs)
             probs.extend(self.rpmdb.check_duplicates(iopkgs))
 
+        if chkcmd.intersection(set(('all', 'obsoleted'))):
+            probs.extend(self.rpmdb.check_obsoleted())
+
+        if chkcmd.intersection(set(('all', 'provides'))):
+            probs.extend(self.rpmdb.check_provides())
+
         header(len(probs))
         for prob in sorted(probs):
             out(prob)
diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index e113802..e18df3f 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -114,6 +114,23 @@ class RPMDBProblemDuplicate(RPMDBProblem):
         return _("%s is a duplicate with %s") % (self.pkg, self.duplicate)
 
 
+class RPMDBProblemObsoleted(RPMDBProblem):
+    def __init__(self, pkg, **kwargs):
+        RPMDBProblem.__init__(self, pkg, "obsoleted", **kwargs)
+
+    def __str__(self):
+        return _("%s is obsoleted by %s") % (self.pkg, self.obsoleter)
+
+
+class RPMDBProblemProvides(RPMDBProblem):
+    def __init__(self, pkg, **kwargs):
+        RPMDBProblem.__init__(self, pkg, "provides", **kwargs)
+
+    def __str__(self):
+        return _("%s provides %s but it cannot be found") % (self.pkg,
+                                                             self.provide)
+
+
 class RPMDBPackageSack(PackageSackBase):
     '''
     Represent rpmdb as a packagesack
@@ -1298,6 +1315,32 @@ class RPMDBPackageSack(PackageSackBase):
             problems.append(RPMDBProblemDuplicate(pkg, duplicate=last))
         return problems
 
+    def check_obsoleted(self):
+        """ Checks for any packages which are obsoleted by other packages. """
+        obsoleters = []
+        problems = []
+        for pkg in sorted(self.returnPackages()):
+            if not pkg.obsoletes:
+                continue
+            obsoleters.append(pkg)
+        for pkg in sorted(self.returnPackages()):
+            provtup = (pkg.name, 'EQ', (pkg.epoch, pkg.version, pkg.release))
+            for obspo in obsoleters:
+                if obspo.inPrcoRange('obsoletes', provtup):
+                    problems.append(RPMDBProblemObsoleted(pkg, obsoleter=obspo))
+        return problems
+
+    def check_provides(self):
+        """ For each package, check that a provides search for it's name (and
+            everything it provides) finds it. """
+        problems = []
+        for pkg in sorted(self.returnPackages()):
+            for provtup in pkg.provides:
+                name, flags, version = provtup
+                if pkg not in self.getProvides(name, flags, version):
+                    problems.append(RPMDBProblemProvides(pkg, provide=provtup))
+                    break
+        return problems
 
 def _sanitize(path):
     return path.replace('/', '').replace('~', '')
commit e27832b442d39b3cfb525bcdf6875a55bf890e45
Author: James Antill <james at and.org>
Date:   Wed Apr 14 18:25:22 2010 -0400

    Enable "big update" speedup, disable if a repo. doesn't have pkgfiles index.

diff --git a/test/testbase.py b/test/testbase.py
index b4ce5d7..44d1959 100644
--- a/test/testbase.py
+++ b/test/testbase.py
@@ -46,10 +46,21 @@ class FakeConf(object):
         self.uid = 0
         self.groupremove_leaf_only = False
 
+class FakeSack:
+    """ Fake PackageSack to use with FakeRepository"""
+    def __init__(self):
+        pass # This is fake, so do nothing
+    
+    def have_fastSearchFiles(self):
+        return True
+
 class FakeRepo(object):
 
+    __fake_sack = FakeSack()
     def __init__(self, id=None,sack=None):
         self.id = id
+        if sack is None:
+            sack = self.__fake_sack
         self.sack = sack
         self.cost = 1000
 
diff --git a/yum/packageSack.py b/yum/packageSack.py
index 7a5ce7a..e63a8d7 100644
--- a/yum/packageSack.py
+++ b/yum/packageSack.py
@@ -152,6 +152,10 @@ class PackageSackBase(object):
         """returns a dict of obsoletes dict[obsoleting pkgtuple] = [list of obs]"""
         raise NotImplementedError()
 
+    def have_fastSearchFiles(self):
+        """ Is calling searchFiles() faster than using """
+        raise NotImplementedError()
+
     def searchFiles(self, name):
         """return list of packages by filename"""
         raise NotImplementedError()
@@ -772,10 +776,11 @@ class PackageSack(PackageSackBase):
             
         return obs
         
+    def have_fastSearchFiles(self):
+        return True
+
     def searchFiles(self, name):
-        """return list of packages by filename
-           FIXME - need to add regex match against keys in file list
-        """
+        """ Return list of packages by filename. """
         self._checkIndexes(failure='build')
         if self.filenames.has_key(name):
             return self.filenames[name]
diff --git a/yum/packages.py b/yum/packages.py
index 427893b..289660d 100644
--- a/yum/packages.py
+++ b/yum/packages.py
@@ -159,6 +159,9 @@ class FakeSack:
     def __init__(self):
         pass # This is fake, so do nothing
     
+    def have_fastSearchFiles(self):
+        return True
+
     def delPackage(self, obj):
         """delete a pkgobject, do nothing, but make localpackages work with --skip-broken"""
         pass # This is fake, so do nothing
diff --git a/yum/sqlitesack.py b/yum/sqlitesack.py
index b5cea0e..74c793a 100644
--- a/yum/sqlitesack.py
+++ b/yum/sqlitesack.py
@@ -842,6 +842,30 @@ class YumSqlitePackageSack(yumRepo.YumPackageSack):
         return misc.unique(results)
         
     @catchSqliteException
+    def _have_fastSearchFiles(self):
+        """ Return true if searchFiles() is always fast, basically relies on
+            "CREATE INDEX pkgfiles ON files (pkgKey);" existing. """
+
+        for (rep,cache) in self.primarydb.items():
+            if rep in self._all_excludes:
+                continue
+            cur = cache.cursor()
+            executeSQL(cur, "PRAGMA index_info(pkgfiles)")
+            #  If we get anything, we're fine. There might be a better way of
+            # saying "anything" but this works.
+            for ob in cur:
+                break
+            else:
+                return False
+
+        return True
+
+    def have_fastSearchFiles(self):
+        if not hasattr(self, '_cached_have_fastSearchFiles'):
+            self._cached_have_fastSearchFiles = self._have_fastSearchFiles()
+        return self._cached_have_fastSearchFiles
+
+    @catchSqliteException
     def searchFiles(self, name, strict=False):
         """search primary if file will be in there, if not, search filelists, use globs, if possible"""
         
diff --git a/yum/transactioninfo.py b/yum/transactioninfo.py
index e7b60de..cad36f4 100644
--- a/yum/transactioninfo.py
+++ b/yum/transactioninfo.py
@@ -89,9 +89,7 @@ class TransactionData:
         self.pkgSack = None
         self.pkgSackPackages = 0
         self.localSack = PackageSack()
-        # FIXME: This is turned off atm. ... it'll be turned on when
-        #        the new yum-metadata-parser with the "pkgfiles" index is std.
-        self._inSack = None # GetProvReqOnlyPackageSack()
+        self._inSack = GetProvReqOnlyPackageSack()
 
         # lists of txmbrs in their states - just placeholders
         self.instgroups = []
@@ -239,7 +237,11 @@ class TransactionData:
         elif isinstance(txmember.po, YumAvailablePackageSqlite):
             self.pkgSackPackages += 1
         if self._inSack is not None and txmember.output_state in TS_INSTALL_STATES:
-            self._inSack.addPackage(txmember.po)
+            if not txmember.po.repo.sack.have_fastSearchFiles():
+                # In theory we could keep this on if a "small" repo. fails
+                self._inSack = None
+            else:
+                self._inSack.addPackage(txmember.po)
 
         if self.conditionals.has_key(txmember.name):
             for pkg in self.conditionals[txmember.name]:


More information about the Yum-commits mailing list