On Fri, 11 Feb 2011, James Antill wrote:
Gah, another reason to hate auto_close ... ACK.
Can you add a comment to the ts.close() calls though, saying something
like "note all 'mi' have to be gone when we call this" or something.
Here's an alternative approach you might find more attractive, as instead
of adding yet more cruft it:
- hides away auto_close inside a single function
- eliminates the dangling iterator issue
- removes code duplication by handling gpg-pubkey filtering centrally
- should be compatible with all historical rpm brokenness in this area
_header_from_index() could be converted to use this too, but if it's
expected to return headers for gpg-pubkeys too then _get_packages() will
need a switch to enable/disable the filtering.
- Panu -
diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index 0982a7c..60ba840 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -378,54 +378,36 @@ class RPMDBPackageSack(PackageSackBase):
pass
def searchAll(self, name, query_type='like'):
- ts = self.readOnlyTS()
result = {}
# check provides
tag = self.DEP_TABLE['provides'][0]
- mi = ts.dbMatch()
- mi.pattern(tag, rpm.RPMMIRE_GLOB, name)
- for hdr in mi:
- if hdr['name'] == 'gpg-pubkey':
- continue
- pkg = self._makePackageObject(hdr, mi.instance())
+ mi = self._get_packages(patterns=[(tag, rpm.RPMMIRE_GLOB, name)])
+ for hdr, idx in mi:
+ pkg = self._makePackageObject(hdr, idx)
result.setdefault(pkg.pkgid, pkg)
- del mi
fileresults = self.searchFiles(name)
for pkg in fileresults:
result.setdefault(pkg.pkgid, pkg)
- if self.auto_close:
- self.ts.close()
-
return result.values()
def searchFiles(self, name):
"""search the filelists in the rpms for anything matching name"""
- ts = self.readOnlyTS()
result = {}
name = os.path.normpath(name)
- mi = ts.dbMatch('basenames', name)
# Note that globs can't be done. As of 4.8.1:
# mi.pattern('basenames', rpm.RPMMIRE_GLOB, name)
# ...produces no results.
- for hdr in mi:
- if hdr['name'] == 'gpg-pubkey':
- continue
- pkg = self._makePackageObject(hdr, mi.instance())
+ for hdr, idx in self._get_packages('basenames', name):
+ pkg = self._makePackageObject(hdr, idx)
result.setdefault(pkg.pkgid, pkg)
- del mi
- result = result.values()
-
- if self.auto_close:
- self.ts.close()
-
- return result
+ return result.values()
def searchPrco(self, name, prcotype):
@@ -438,21 +420,15 @@ class RPMDBPackageSack(PackageSackBase):
if misc.re_glob(n):
glob = True
- ts = self.readOnlyTS()
result = {}
tag = self.DEP_TABLE[prcotype][0]
- mi = ts.dbMatch(tag, misc.to_utf8(n))
- for hdr in mi:
- if hdr['name'] == 'gpg-pubkey':
- continue
- po = self._makePackageObject(hdr, mi.instance())
+ for hdr, idx in self._get_packages(tag, misc.to_utf8(n)):
+ po = self._makePackageObject(hdr, idx)
if not glob:
if po.checkPrco(prcotype, (n, f, (e,v,r))):
result[po.pkgid] = po
else:
result[po.pkgid] = po
- del mi
-
# If it's not a provides or filename, we are done
if prcotype == 'provides' and name[0] == '/':
@@ -463,9 +439,6 @@ class RPMDBPackageSack(PackageSackBase):
result = result.values()
self._cache[prcotype][name] = result
- if self.auto_close:
- self.ts.close()
-
return result
def searchProvides(self, name):
@@ -636,18 +609,13 @@ class RPMDBPackageSack(PackageSackBase):
if self._cached_conflicts_data is None:
result = {}
- ts = self.readOnlyTS()
- mi = ts.dbMatch('conflictname')
-
- for hdr in mi:
- if hdr['name'] == 'gpg-pubkey': # Just in case...
- continue
+ for hdr, idx in self._get_packages('conflictname'):
if not hdr[rpm.RPMTAG_CONFLICTNAME]:
# Pre. rpm-4.9.x the above dbMatch() does nothing.
continue
- po = self._makePackageObject(hdr, mi.instance())
+ po = self._makePackageObject(hdr, idx)
result[po.pkgid] = po
if po._has_hdr:
continue # Unlikely, but, meh...
@@ -659,9 +627,6 @@ class RPMDBPackageSack(PackageSackBase):
del po.hdr
self._cached_conflicts_data = result.values()
- if self.auto_close:
- self.ts.close()
-
return self._cached_conflicts_data
def _write_conflicts_new(self, pkgs, rpmdbv):
@@ -1190,19 +1155,31 @@ class RPMDBPackageSack(PackageSackBase):
return [ self._makePackageObject(h, mi) for (h, mi) in
ts.returnLeafNodes(headers=True) ]
# Helper functions
- def _all_packages(self):
- '''Generator that yield (header, index) for all packages
+ def _get_packages(self, *args, **kwds):
+ '''dbMatch() wrapper generator that yields (header, index) for matches
'''
+ if 'patterns' in kwds:
+ patterns = kwds.pop('patterns')
+ else:
+ patterns = []
+
ts = self.readOnlyTS()
- mi = ts.dbMatch()
+ mi = ts.dbMatch(*args, **kwds)
+ for (tag, tp, pat) in patterns:
+ mi.pattern(tag, tp, pat)
+ for h in mi:
+ if h['name'] != 'gpg-pubkey':
+ yield (h, mi.instance())
- for hdr in mi:
- if hdr['name'] != 'gpg-pubkey':
- yield (hdr, mi.instance())
del mi
if self.auto_close:
self.ts.close()
+ def _all_packages(self):
+ '''Generator that yield (header, index) for all packages
+ '''
+ return self._get_packages()
+
def _header_from_index(self, idx):
"""returns a package header having been given an index"""
warnings.warn('_header_from_index() will go away in a future version
of Yum.\n',
@@ -1254,18 +1231,16 @@ class RPMDBPackageSack(PackageSackBase):
ts = self.readOnlyTS()
if name is not None:
- mi = ts.dbMatch('name', name)
+ mi = self._get_packages('name', name)
elif arch is not None:
- mi = ts.dbMatch('arch', arch)
+ mi = self._get_packages('arch', arch)
else:
- mi = ts.dbMatch()
+ mi = self._get_packages()
self._completely_loaded = True
done = False
- for hdr in mi:
- if hdr['name'] == 'gpg-pubkey':
- continue
- po = self._makePackageObject(hdr, mi.instance())
+ for hdr, idx in mi:
+ po = self._makePackageObject(hdr, idx)
# We create POs out of all matching names, even if we don't return
# them.
self._pkgnames_loaded.add(po.name)
@@ -1277,9 +1252,6 @@ class RPMDBPackageSack(PackageSackBase):
else:
ret.append(po)
- if self.auto_close:
- self.ts.close()
-
if not done and name is not None:
self._pkgname_fails.add(name)
- Panu -
_______________________________________________
Yum-devel mailing list
[email protected]
http://lists.baseurl.org/mailman/listinfo/yum-devel