On Mon, 2007-01-15 at 19:55 +0000, David Lutterkort wrote:
> I attach a patch that turns that around so that the database is queried
> directly when the user runs 'yum install'
My previous patch was braindead when combining the unmatched entries
from several repos. This updated patch fixes that.
David
Index: cli.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/cli.py,v
retrieving revision 1.247
diff -u -r1.247 cli.py
--- cli.py 7 Dec 2006 23:25:56 -0000 1.247
+++ cli.py 17 Jan 2007 01:43:22 -0000
@@ -511,7 +511,6 @@
self.doRepoSetup()
self.doRpmDBSetup()
- avail = self.pkgSack.returnPackages()
toBeInstalled = {} # keyed on name
passToUpdate = [] # list of pkgtups to pass along to updatecheck
@@ -524,8 +523,7 @@
# no matter what we don't go looking at repos
arglist = [arg]
- exactmatch, matched, unmatched = parsePackages(avail, arglist,
- casematch=1)
+ exactmatch, matched, unmatched = self.pkgSack.parsePackages(arglist)
if len(unmatched) > 0: # if we get back anything in unmatched, check it for a virtual-provide
arg = unmatched[0] #only one in there
self.verbose_logger.debug('Checking for virtual provide or file-provide for %s',
@@ -538,7 +536,7 @@
arg = '%s:%s-%s-%s.%s' % (mypkg.epoch, mypkg.name,
mypkg.version, mypkg.release,
mypkg.arch)
- emtch, mtch, unmtch = parsePackages(avail, [arg])
+ emtch, mtch, unmtch = self.pkgSack.parsePackages([arg])
exactmatch.extend(emtch)
matched.extend(mtch)
Index: yum/packageSack.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/yum/packageSack.py,v
retrieving revision 1.23
diff -u -r1.23 packageSack.py
--- yum/packageSack.py 19 Dec 2006 03:43:31 -0000 1.23
+++ yum/packageSack.py 17 Jan 2007 01:43:23 -0000
@@ -18,6 +18,7 @@
import warnings
import re
import fnmatch
+import misc
class PackageSackBase(object):
"""Base class that provides the interface for PackageSacks."""
@@ -317,6 +318,30 @@
def searchAll(self, arg, query_type):
return self._computeAggregateListResult("searchAll", arg, query_type)
+ def parsePackages(self, pkgspecs):
+ matched = []
+ exactmatch = []
+ unmatched = None
+ for sack in self.sacks.values():
+ if hasattr(sack, "parsePackages"):
+ e, m, u = [], [], []
+ try:
+ e, m, u = sack.parsePackages(pkgspecs)
+ except PackageSackError:
+ continue
+
+ exactmatch.extend(e)
+ matched.extend(m)
+ if unmatched:
+ unmatched = unmatched.intersection(set(u))
+ else:
+ unmatched = set(u)
+
+ matched = misc.unique(matched)
+ exactmatch = misc.unique(exactmatch)
+ unmatched = list(unmatched)
+ return exactmatch, matched, unmatched
+
def _computeAggregateListResult(self, methodName, *args):
result = []
for sack in self.sacks.values():
Index: yum/sqlitesack.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/yum/sqlitesack.py,v
retrieving revision 1.54
diff -u -r1.54 sqlitesack.py
--- yum/sqlitesack.py 15 Dec 2006 14:40:55 -0000 1.54
+++ yum/sqlitesack.py 17 Jan 2007 01:43:23 -0000
@@ -27,7 +27,7 @@
import Errors
import misc
-from sqlutils import executeSQL
+from sqlutils import executeSQL, globToLike
# Simple subclass of YumAvailablePackage that can load 'simple headers' from
# the database when they are requested
@@ -499,6 +499,34 @@
raise Errors.PackageSackError, 'No Package Matching %s' % name
return misc.newestInList(allpkg)
+ # Do what packages.parsePackages does, but query the DB directly
+ def parsePackages(self, pkgspecs):
+ matched = []
+ exactmatch = []
+ unmatched = list(pkgspecs)
+ for p in pkgspecs:
+ q = globToLike(p)
+ if q:
+ query = PARSE_QUERY % ({ "op": "like", "q": q })
+ matchres = matched
+ else:
+ query = PARSE_QUERY % ({ "op": "=", "q": p })
+ matchres = exactmatch
+
+ for (rep, db) in self.primarydb.items():
+ cur = db.cursor()
+ executeSQL(cur, query)
+ res = cur.fetchall()
+ if len(res) > 0:
+ unmatched.remove(p)
+ pos = map(lambda x: self.pc(rep,self.db2class(x,True)), res)
+ matchres.extend(pos)
+
+ exactmatch = misc.unique(exactmatch)
+ matched = misc.unique(matched)
+ unmatched = misc.unique(unmatched)
+ return exactmatch, matched, unmatched
+
def returnPackages(self, repoid=None):
"""Returns a list of packages, only containing nevra information """
returnList = []
@@ -506,7 +534,7 @@
if (repoid == None or repoid == repo.id):
cur = cache.cursor()
executeSQL(cur, "select pkgId,name,epoch,version,release,arch from packages")
- for x in cur.fetchall():
+ for x in cur:
if (self.excludes[repo].has_key(x['pkgId'])):
continue
returnList.append(self.pc(repo,self.db2class(x,True)))
@@ -585,3 +613,18 @@
string2ft = {'f':'file','d': 'dir','g': 'ghost'}
return [string2ft[x] for x in filetypestring]
+
+# Query used by parsePackages
+# op is either '=' or 'like', q is the search term
+# Check against name, nameArch, nameVerRelArch, nameVer, nameVerRel,
+# envra, nevra
+PARSE_QUERY = """
+select pkgId, name, arch, epoch, version, release from packages
+where name %(op)s '%(q)s'
+ or name || '.' || arch %(op)s '%(q)s'
+ or name || '-' || version %(op)s '%(q)s'
+ or name || '-' || version || '-' || release %(op)s '%(q)s'
+ or name || '-' || version || '-' || release || '.' || arch %(op)s '%(q)s'
+ or epoch || ':' || name || '-' || version || '-' || release || '.' || arch %(op)s '%(q)s'
+ or name || '-' || epoch || ':' || version || '-' || release || '.' || arch %(op)s '%(q)s'
+"""
Index: yum/sqlutils.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/yum/sqlutils.py,v
retrieving revision 1.1
diff -u -r1.1 sqlutils.py
--- yum/sqlutils.py 5 Dec 2006 20:51:29 -0000 1.1
+++ yum/sqlutils.py 17 Jan 2007 01:43:24 -0000
@@ -150,5 +150,16 @@
else:
executeSQL = executeSQLPyFormat
+# Convert the string S from a glob expression containing '*' and '?'
+# to a search expression for a SQL like query containing '%' and '?'
+# Return None if S can be used with a straight equal comparison, i.e. does
+# not contain at least one '*' or '?'
+def globToLike(s):
+ if s.find('*') >= 0:
+ return s.replace('*', '%')
+ elif s.find('?') >= 0:
+ return s
+ else:
+ return None
_______________________________________________
Yum-devel mailing list
[email protected]
https://lists.dulug.duke.edu/mailman/listinfo/yum-devel