Hi!

The attached patches address the issue brought up.

yum-whatProvides-2.diff fixes the _excluded and put the file queries in a smarter order.

yum-whatProvides-3.diff additionally (sorry, no separated patch) removes duplicate code by calling rangeCompare.

rangeCompare currently returns True if the flag of the provtuple is None. This was not the case with the old inPrcoRange implementation. Any comments about that?

Florian
? anaconda.prof.0
Index: rpmUtils/miscutils.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/rpmUtils/miscutils.py,v
retrieving revision 1.21
diff -u -r1.21 miscutils.py
--- rpmUtils/miscutils.py	7 Apr 2007 18:23:15 -0000	1.21
+++ rpmUtils/miscutils.py	27 Apr 2007 09:01:10 -0000
@@ -155,6 +155,68 @@
             return 1
     return 0
 
+def rangeCompare(reqtuple, provtuple):
+    """returns true if the package has a the prco that satisfies 
+    the reqtuple range, assume false."""
+    (reqn, reqf, (reqe, reqv, reqr)) = reqtuple
+    (n, f, (e, v, r)) = provtuple
+    if reqn != n:
+        return 0
+
+    if f is None or reqf is None:
+        return 1
+    
+    # and you thought we were done having fun
+    # if the requested release is left out then we have
+    # to remove release from the package prco to make sure the match
+    # is a success - ie: if the request is EQ foo 1:3.0.0 and we have 
+    # foo 1:3.0.0-15 then we have to drop the 15 so we can match
+    if reqr is None:
+        r = None
+    if reqe is None:
+        e = None
+    if reqv is None: # just for the record if ver is None then we're going to segfault
+        v = None
+
+    # if we just require foo-version, then foo-version-* will match
+    if r is None:
+        reqr = None
+
+    rc = rpmUtils.miscutils.compareEVR((e, v, r), (reqe, reqv, reqr))
+
+    # does not match unless
+    if rc >= 1:
+        if reqf in ['GT', 'GE', 4, 12]:
+            return 1
+        if reqf in ['EQ', 8]:
+            if f in ['LE', 10]:
+                return 1
+    if rc == 0:
+        if reqf in ['GT', 4]:
+            if f in ['GT', 'GE', 4, 12]:
+                return 1
+        if reqf in ['GE', 12]:
+            if f in ['GT', 'GE', 'EQ', 'LE', 4, 12, 8, 10]:
+                return 1
+        if reqf in ['EQ', 8]:
+            if f in ['EQ', 'GE', 'LE', 8, 12, 10]:
+                return 1
+        if reqf in ['LE', 10]:
+            if f in ['EQ', 'LE', 'LT', 'GE', 8, 10, 2, 12]:
+                return 1
+        if reqf in ['LT', 2]:
+            if f in ['LE', 'LT', 10, 2]:
+                return 1
+    if rc <= -1:
+        if reqf in ['GT', 'GE', 'EQ', 4, 12, 8]:
+            if f in ['GT', 'GE', 4, 12]:
+                return 1
+        if reqf in ['LE', 'LT', 10, 2]:
+            return 1
+
+    return 0
+    
+
 ###########
 # Title: Remove duplicates from a sequence
 # Submitter: Tim Peters 
Index: yum/depsolve.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/yum/depsolve.py,v
retrieving revision 1.163
diff -u -r1.163 depsolve.py
--- yum/depsolve.py	24 Apr 2007 21:02:50 -0000	1.163
+++ yum/depsolve.py	27 Apr 2007 09:01:10 -0000
@@ -126,32 +126,8 @@
                     matched = 1
             if not matched:
                 self.doSackFilelistPopulate()
-            
-        pkgs = self.pkgSack.searchProvides(name)
-        
-        
-        if flags == 0:
-            flags = None
-        if type(version) in (types.StringType, types.NoneType, types.UnicodeType):
-            (r_e, r_v, r_r) = rpmUtils.miscutils.stringToVersion(version)
-        elif type(version) in (types.TupleType, types.ListType): # would this ever be a ListType?
-            (r_e, r_v, r_r) = version
-        
-        defSack = ListPackageSack() # holder for items definitely providing this dep
-        
-        for po in pkgs:
-            self.verbose_logger.log(logginglevels.DEBUG_2,
-                'Potential match for %s from %s', name, po)
-            if name[0] == '/' and r_v is None:
-                # file dep add all matches to the defSack
-                defSack.addPackage(po)
-                continue
 
-            if po.checkPrco('provides', (name, flags, (r_e, r_v, r_r))):
-                defSack.addPackage(po)
-                self.verbose_logger.debug('Matched %s to require for %s', po, name)
-        
-        return defSack
+        return ListPackageSack(self.pkgSack.whatProvides(name, flags, version))
         
     def allowedMultipleInstalls(self, po):
         """takes a packageObject, returns 1 or 0 depending on if the package 
Index: yum/packageSack.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/yum/packageSack.py,v
retrieving revision 1.29
diff -u -r1.29 packageSack.py
--- yum/packageSack.py	4 Mar 2007 21:45:16 -0000	1.29
+++ yum/packageSack.py	27 Apr 2007 09:01:11 -0000
@@ -64,6 +64,14 @@
         """return list of pkgobject matching the (n,a,e,v,r) tuple"""
         (n,a,e,v,r) = pkgtup
         return self.searchNevra(name=n, arch=a, epoch=e, ver=v, rel=r)
+
+    def whatProvides(self, name, flags, version):
+        """return list of package providing the name flags, version"""
+        raise NotImplementedError()
+
+    def whatRequires(self, name, flags, version):
+        """return list of package requiring the name flags, version"""
+        raise NotImplementedError()
         
     def searchRequires(self, name):
         """return list of package requiring the name (any evr and flag)"""
@@ -231,6 +239,16 @@
         """return list of pkgobjects matching the nevra requested"""
         return self._computeAggregateListResult("searchNevra", name, epoch, ver, rel, arch)
 
+    def whatProvides(self, name, flags, version):
+        """return list of package providing the name flags, version"""
+        return self._computeAggregateListResult("whatProvides",
+                                                name, flags, version)
+
+    def whatRequires(self, name, flags, version):
+        """return list of package requiring the name flags, version"""
+        return self._computeAggregateListResult("whatRequires",
+                                                name, flags, version)
+
     def searchRequires(self, name):
         """return list of package requiring the name (any evr and flag)"""
         return self._computeAggregateListResult("searchRequires", name)
Index: yum/sqlitesack.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/yum/sqlitesack.py,v
retrieving revision 1.97
diff -u -r1.97 sqlitesack.py
--- yum/sqlitesack.py	25 Apr 2007 18:28:31 -0000	1.97
+++ yum/sqlitesack.py	27 Apr 2007 09:01:11 -0000
@@ -32,6 +32,7 @@
 import warnings
 
 from sqlutils import executeSQL
+import rpmUtils.miscutils
 
 class YumAvailablePackageSqlite(YumAvailablePackage, PackageObject, RpmBase):
     def __init__(self, repo, db_obj):
@@ -420,6 +421,66 @@
                 pkgs.append(ob)
         
         return pkgs
+
+
+    def _search(self, prcotype, name, flags, version):
+        if flags == 0:
+            flags = None
+        if type(version) in (str, type(None), unicode):
+            req = (name, flags, rpmUtils.miscutils.stringToVersion(
+                version))
+        elif type(version) in (tuple, list): # would this ever be a list?
+            req = (name, flags, version)
+
+        result = [ ]
+        
+        for (rep,cache) in self.primarydb.items():
+            cur = cache.cursor()
+            executeSQL(cur, "select packages.*, %s.name as n, %s.flags as f, "
+                       "%s.epoch as e, %s.version as v, %s.release as r "
+                       "from %s,packages "
+                       "where %s.name = ? and "
+                       "%s.pkgKey=packages.pkgKey" %
+                       ((prcotype,) * 8),
+                       (name,))
+            for x in cur:
+                if self._excluded(rep,x['pkgId']):
+                    continue
+                val = (x[-5], x[-4], x[-3:])
+                if rpmUtils.miscutils.rangeCompare(req, val):
+                    result.append(self.pc(rep,x))
+                    
+        if prcotype != 'provides' or name[0] != '/':
+            return result
+
+        matched = 0
+        globs = ['.*bin\/.*', '^\/etc\/.*', '^\/usr\/lib\/sendmail$']
+        for thisglob in globs:
+            globc = re.compile(thisglob)
+            if globc.match(name):
+                matched = 1
+
+        if not matched: # if its not in the primary.xml files
+            # search the files.xml file info
+            result.extend(self.searchFiles(name))
+            return result
+
+        # If it is a filename, search the primary.xml file info
+        for (rep,cache) in self.primarydb.items():
+            cur = cache.cursor()
+            executeSQL(cur, "select DISTINCT packages.* from files,packages where files.name = ? and files.pkgKey = packages.pkgKey", (name,))
+            for x in cur:
+                if self._excluded(rep,x['pkgId']):
+                    continue
+                result.append(self.pc(rep,x))
+        
+        return result
+
+    def whatProvides(self, name, flags, version):
+        return self._search("provides", name, flags, version)
+
+    def whatRequires(self, name, flags, version):
+        return self._search("requires", name, flags, version)
         
     
     def searchPrco(self, name, prcotype):
? anaconda.prof.0
Index: rpmUtils/miscutils.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/rpmUtils/miscutils.py,v
retrieving revision 1.21
diff -u -r1.21 miscutils.py
--- rpmUtils/miscutils.py	7 Apr 2007 18:23:15 -0000	1.21
+++ rpmUtils/miscutils.py	27 Apr 2007 09:23:05 -0000
@@ -126,10 +126,20 @@
        ex: foo >= 2.1-1"""
     # we only ever get here if we have a versioned prco
     # nameonly shouldn't ever raise it
-    (reqn, reqf, (reqe, reqv, reqr)) = reqtuple
+    #(reqn, reqf, (reqe, reqv, reqr)) = reqtuple
     (n, a, e, v, r) = pkgtuple
-    #simple failures
-    if reqn != n: return 0
+    return rangeCompare(reqtuple, (n, 'EQ', (e, v, r)))
+
+def rangeCompare(reqtuple, provtuple):
+    """returns true if provtuple satisfies reqtuple"""
+    (reqn, reqf, (reqe, reqv, reqr)) = reqtuple
+    (n, f, (e, v, r)) = provtuple
+    if reqn != n:
+        return 0
+
+    if f is None or reqf is None:
+        return 1
+    
     # and you thought we were done having fun
     # if the requested release is left out then we have
     # to remove release from the package prco to make sure the match
@@ -141,19 +151,54 @@
         e = None
     if reqv is None: # just for the record if ver is None then we're going to segfault
         v = None
-        
-    rc = compareEVR((e, v, r), (reqe, reqv, reqr))
-            
+
+    # if we just require foo-version, then foo-version-* will match
+    if r is None:
+        reqr = None
+
+    rc = rpmUtils.miscutils.compareEVR((e, v, r), (reqe, reqv, reqr))
+
+    # does not match unless
     if rc >= 1:
         if reqf in ['GT', 'GE', 4, 12]:
             return 1
+        if reqf in ['EQ', 8]:
+            if f in ['LE', 10]:
+                return 1
     if rc == 0:
-        if reqf in ['GE', 'LE', 'EQ', 8, 10, 12]:
-            return 1
+        if reqf in ['GT', 4]:
+            if f in ['GT', 'GE', 4, 12]:
+                return 1
+        if reqf in ['GE', 12]:
+            if f in ['GT', 'GE', 'EQ', 'LE', 4, 12, 8, 10]:
+                return 1
+        if reqf in ['EQ', 8]:
+            if f in ['EQ', 'GE', 'LE', 8, 12, 10]:
+                return 1
+        if reqf in ['LE', 10]:
+            if f in ['EQ', 'LE', 'LT', 'GE', 8, 10, 2, 12]:
+                return 1
+        if reqf in ['LT', 2]:
+            if f in ['LE', 'LT', 10, 2]:
+                return 1
     if rc <= -1:
-        if reqf in ['LT', 'LE', 2, 10]:
+        if reqf in ['GT', 'GE', 'EQ', 4, 12, 8]:
+            if f in ['GT', 'GE', 4, 12]:
+                return 1
+        if reqf in ['LE', 'LT', 10, 2]:
             return 1
+#                if rc >= 1:
+#                    if reqf in ['GT', 'GE', 4, 12]:
+#                        return 1
+#                if rc == 0:
+#                    if reqf in ['GE', 'LE', 'EQ', 8, 10, 12]:
+#                        return 1
+#                if rc <= -1:
+#                    if reqf in ['LT', 'LE', 2, 10]:
+#                        return 1
+
     return 0
+    
 
 ###########
 # Title: Remove duplicates from a sequence
Index: yum/depsolve.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/yum/depsolve.py,v
retrieving revision 1.163
diff -u -r1.163 depsolve.py
--- yum/depsolve.py	24 Apr 2007 21:02:50 -0000	1.163
+++ yum/depsolve.py	27 Apr 2007 09:23:05 -0000
@@ -126,32 +126,8 @@
                     matched = 1
             if not matched:
                 self.doSackFilelistPopulate()
-            
-        pkgs = self.pkgSack.searchProvides(name)
-        
-        
-        if flags == 0:
-            flags = None
-        if type(version) in (types.StringType, types.NoneType, types.UnicodeType):
-            (r_e, r_v, r_r) = rpmUtils.miscutils.stringToVersion(version)
-        elif type(version) in (types.TupleType, types.ListType): # would this ever be a ListType?
-            (r_e, r_v, r_r) = version
-        
-        defSack = ListPackageSack() # holder for items definitely providing this dep
-        
-        for po in pkgs:
-            self.verbose_logger.log(logginglevels.DEBUG_2,
-                'Potential match for %s from %s', name, po)
-            if name[0] == '/' and r_v is None:
-                # file dep add all matches to the defSack
-                defSack.addPackage(po)
-                continue
 
-            if po.checkPrco('provides', (name, flags, (r_e, r_v, r_r))):
-                defSack.addPackage(po)
-                self.verbose_logger.debug('Matched %s to require for %s', po, name)
-        
-        return defSack
+        return ListPackageSack(self.pkgSack.whatProvides(name, flags, version))
         
     def allowedMultipleInstalls(self, po):
         """takes a packageObject, returns 1 or 0 depending on if the package 
Index: yum/packageSack.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/yum/packageSack.py,v
retrieving revision 1.29
diff -u -r1.29 packageSack.py
--- yum/packageSack.py	4 Mar 2007 21:45:16 -0000	1.29
+++ yum/packageSack.py	27 Apr 2007 09:23:05 -0000
@@ -64,6 +64,14 @@
         """return list of pkgobject matching the (n,a,e,v,r) tuple"""
         (n,a,e,v,r) = pkgtup
         return self.searchNevra(name=n, arch=a, epoch=e, ver=v, rel=r)
+
+    def whatProvides(self, name, flags, version):
+        """return list of package providing the name flags, version"""
+        raise NotImplementedError()
+
+    def whatRequires(self, name, flags, version):
+        """return list of package requiring the name flags, version"""
+        raise NotImplementedError()
         
     def searchRequires(self, name):
         """return list of package requiring the name (any evr and flag)"""
@@ -231,6 +239,16 @@
         """return list of pkgobjects matching the nevra requested"""
         return self._computeAggregateListResult("searchNevra", name, epoch, ver, rel, arch)
 
+    def whatProvides(self, name, flags, version):
+        """return list of package providing the name flags, version"""
+        return self._computeAggregateListResult("whatProvides",
+                                                name, flags, version)
+
+    def whatRequires(self, name, flags, version):
+        """return list of package requiring the name flags, version"""
+        return self._computeAggregateListResult("whatRequires",
+                                                name, flags, version)
+
     def searchRequires(self, name):
         """return list of package requiring the name (any evr and flag)"""
         return self._computeAggregateListResult("searchRequires", name)
Index: yum/packages.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/yum/packages.py,v
retrieving revision 1.101
diff -u -r1.101 packages.py
--- yum/packages.py	25 Apr 2007 20:19:19 -0000	1.101
+++ yum/packages.py	27 Apr 2007 09:23:05 -0000
@@ -259,80 +259,26 @@
         # however, just in case
         # find the named entry in pkgobj, do the comparsion
         for (n, f, (e, v, r)) in self.returnPrco(prcotype):
-            if reqn == n:
-                # found it
-                if f is None:
-                    return 1
-                if f != 'EQ' and prcotype == 'provides':                
-                    # isn't this odd, it's not 'EQ' and it is a provides
-                    # - it really should be EQ
-                    # use the pkgobj's evr for the comparison
-                    if e is None:
-                        e = self.epoch
-                    if v is None:
-                        v = self.ver
-                    if r is None:
-                        r = self.rel
-                    
-                    #(e, v, r) = (self.epoch, self.ver, self.rel)
-                # and you thought we were done having fun
-                # if the requested release is left out then we have
-                # to remove release from the package prco to make sure the match
-                # is a success - ie: if the request is EQ foo 1:3.0.0 and we have 
-                # foo 1:3.0.0-15 then we have to drop the 15 so we can match
-                if reqr is None:
-                    r = None
-                if reqe is None:
-                    e = None
-                if reqv is None: # just for the record if ver is None then we're going to segfault
-                    v = None
+            if reqn != n:
+                continue
 
-                # if we just require foo-version, then foo-version-* will match
+            if f != 'EQ' and prcotype == 'provides':                
+                # isn't this odd, it's not 'EQ' and it is a provides
+                # - it really should be EQ
+                # use the pkgobj's evr for the comparison
+                if e is None:
+                    e = self.epoch
+                if v is None:
+                    v = self.ver
                 if r is None:
-                    reqr = None
+                    r = self.rel
+                #(e, v, r) = (self.epoch, self.ver, self.rel)
+
+            matched = rpmUtils.miscutils.rangeCompare(
+                reqtuple, (n, f, (e, v, r)))
+            if matched:
+                return matched
 
-                rc = rpmUtils.miscutils.compareEVR((e, v, r), (reqe, reqv, reqr))
-                
-                # does not match unless
-                if rc >= 1:
-                    if reqf in ['GT', 'GE', 4, 12]:
-                        return 1
-                    if reqf in ['EQ', 8]:
-                        if f in ['LE', 10]:
-                            return 1
-                if rc == 0:
-                    if reqf in ['GT', 4]:
-                        if f in ['GT', 'GE', 4, 12]:
-                            return 1
-                    if reqf in ['GE', 12]:
-                        if f in ['GT', 'GE', 'EQ', 'LE', 4, 12, 8, 10]:
-                            return 1
-                    if reqf in ['EQ', 8]:
-                        if f in ['EQ', 'GE', 'LE', 8, 12, 10]:
-                            return 1
-                    if reqf in ['LE', 10]:
-                        if f in ['EQ', 'LE', 'LT', 'GE', 8, 10, 2, 12]:
-                            return 1
-                    if reqf in ['LT', 2]:
-                        if f in ['LE', 'LT', 10, 2]:
-                            return 1
-                if rc <= -1:
-                    if reqf in ['GT', 'GE', 'EQ', 4, 12, 8]:
-                        if f in ['GT', 'GE', 4, 12]:
-                            return 1
-                    if reqf in ['LE', 'LT', 10, 2]:
-                        return 1
-                
-                
-#                if rc >= 1:
-#                    if reqf in ['GT', 'GE', 4, 12]:
-#                        return 1
-#                if rc == 0:
-#                    if reqf in ['GE', 'LE', 'EQ', 8, 10, 12]:
-#                        return 1
-#                if rc <= -1:
-#                    if reqf in ['LT', 'LE', 2, 10]:
-#                        return 1
         return 0
         
     def returnChangelog(self):
Index: yum/sqlitesack.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/yum/sqlitesack.py,v
retrieving revision 1.97
diff -u -r1.97 sqlitesack.py
--- yum/sqlitesack.py	25 Apr 2007 18:28:31 -0000	1.97
+++ yum/sqlitesack.py	27 Apr 2007 09:23:06 -0000
@@ -32,6 +32,7 @@
 import warnings
 
 from sqlutils import executeSQL
+import rpmUtils.miscutils
 
 class YumAvailablePackageSqlite(YumAvailablePackage, PackageObject, RpmBase):
     def __init__(self, repo, db_obj):
@@ -420,6 +421,66 @@
                 pkgs.append(ob)
         
         return pkgs
+
+
+    def _search(self, prcotype, name, flags, version):
+        if flags == 0:
+            flags = None
+        if type(version) in (str, type(None), unicode):
+            req = (name, flags, rpmUtils.miscutils.stringToVersion(
+                version))
+        elif type(version) in (tuple, list): # would this ever be a list?
+            req = (name, flags, version)
+
+        result = [ ]
+        
+        for (rep,cache) in self.primarydb.items():
+            cur = cache.cursor()
+            executeSQL(cur, "select packages.*, %s.name as n, %s.flags as f, "
+                       "%s.epoch as e, %s.version as v, %s.release as r "
+                       "from %s,packages "
+                       "where %s.name = ? and "
+                       "%s.pkgKey=packages.pkgKey" %
+                       ((prcotype,) * 8),
+                       (name,))
+            for x in cur:
+                if self._excluded(rep,x['pkgId']):
+                    continue
+                val = (x[-5], x[-4], x[-3:])
+                if rpmUtils.miscutils.rangeCompare(req, val):
+                    result.append(self.pc(rep,x))
+                    
+        if prcotype != 'provides' or name[0] != '/':
+            return result
+
+        matched = 0
+        globs = ['.*bin\/.*', '^\/etc\/.*', '^\/usr\/lib\/sendmail$']
+        for thisglob in globs:
+            globc = re.compile(thisglob)
+            if globc.match(name):
+                matched = 1
+
+        if not matched: # if its not in the primary.xml files
+            # search the files.xml file info
+            result.extend(self.searchFiles(name))
+            return result
+
+        # If it is a filename, search the primary.xml file info
+        for (rep,cache) in self.primarydb.items():
+            cur = cache.cursor()
+            executeSQL(cur, "select DISTINCT packages.* from files,packages where files.name = ? and files.pkgKey = packages.pkgKey", (name,))
+            for x in cur:
+                if self._excluded(rep,x['pkgId']):
+                    continue
+                result.append(self.pc(rep,x))
+        
+        return result
+
+    def whatProvides(self, name, flags, version):
+        return self._search("provides", name, flags, version)
+
+    def whatRequires(self, name, flags, version):
+        return self._search("requires", name, flags, version)
         
     
     def searchPrco(self, name, prcotype):
_______________________________________________
Yum-devel mailing list
[email protected]
https://lists.dulug.duke.edu/mailman/listinfo/yum-devel

Reply via email to