* fully add txn support to filesdb

* a cute procedure to enable automatic commits when none provided,
  this one is actually working unlike berkeley db's AUTO_COMMIT. Hah!
This commit is contained in:
Eray Özkural
2005-12-08 15:18:55 +00:00
parent 161ad9dcd5
commit cce8e45eb9
3 changed files with 66 additions and 39 deletions
+10 -5
View File
@@ -712,6 +712,8 @@ Usage: add-repo <repo> <indexuri>
<repo>: name of repository to add <repo>: name of repository to add
<indexuri>: URI of index file <indexuri>: URI of index file
If no repo is given, add-repo pardus-devel repo is added by default
NB: We support only local files (e.g., /a/b/c) and http:// URIs at the moment NB: We support only local files (e.g., /a/b/c) and http:// URIs at the moment
""" """
__metaclass__ = autocommand __metaclass__ = autocommand
@@ -723,10 +725,14 @@ NB: We support only local files (e.g., /a/b/c) and http:// URIs at the moment
def run(self): def run(self):
if len(self.args)>=2: if len(self.args)==2 or len(self.args)==0:
self.init() self.init()
name = self.args[0] if len(self.args)==2:
indexuri = self.args[1] name = self.args[0]
indexuri = self.args[1]
else:
name = 'pardus-devel'
indexuri = 'http://paketler.uludag.org.tr/pardus-devel/pisi-index.xml'
pisi.api.add_repo(name, indexuri) pisi.api.add_repo(name, indexuri)
if ctx.ui.confirm(_('Update PISI database for repository %s?') % name): if ctx.ui.confirm(_('Update PISI database for repository %s?') % name):
pisi.api.update_repo(name) pisi.api.update_repo(name)
@@ -1015,11 +1021,10 @@ Finds the installed package which contains the specified file.
files.append(ctx.filesdb.get_file(path)) files.append(ctx.filesdb.get_file(path))
else: else:
#FIXME: this linear search thing is not working well -- exa #FIXME: this linear search thing is not working well -- exa
files = ctx.filesdb.get_files(path) files = ctx.filesdb.match_files(path)
if files: if files:
for (pkg_name, file_info) in files: for (pkg_name, file_info) in files:
#FIXME: files of the same package can be grouped under package name
ctx.ui.info(_("Package %s has file %s") % (pkg_name, file_info.path)) ctx.ui.info(_("Package %s has file %s") % (pkg_name, file_info.path))
if ctx.config.options.long: if ctx.config.options.long:
ctx.ui.info(_('Type: %s, Hash: %s') % (file_info.type, ctx.ui.info(_('Type: %s, Hash: %s') % (file_info.type,
+27 -16
View File
@@ -46,25 +46,36 @@ class DBShelf:
#def __del__(self): #def __del__(self):
# self.close() # self.close()
def has_key(self, key): def has_key(self, key, txn = None):
return self.db.has_key(key) if txn:
return self.db.has_key(key, txn)
def clear(self, txn = None):
if not txn:
txn = self.dbenv.txn_begin()
try:
for x in self.keys(txn):
del self[x]
except db.DBError, e:
txn.abort()
raise e
txn.commit()
else: else:
return self.db.has_key(key)
def txn_proc(self, proc, txn):
# can be used to txn protect a method automatically
if not txn:
autotxn = self.dbenv.txn_begin()
try:
retval = proc(autotxn)
except db.DBError, e:
autotxn.abort()
raise e
autotxn.commit()
return retval
else:
return proc(txn)
def clear(self, txn = None):
def proc(txn):
for x in self.keys(txn): for x in self.keys(txn):
del self[x] self.delete(txn)
txn_proc(proc, txn)
#def delete(self, txn = None): def delete(self, txn):
# self.db.delete(self, txn def proc(txn):
self.db.delete(txn)
txn_proc(proc, txn)
# another lame pythonic implementation method: # another lame pythonic implementation method:
#def __getattr__(self, name): #def __getattr__(self, name):
+29 -18
View File
@@ -9,16 +9,17 @@
# #
# Please read the COPYING file. # Please read the COPYING file.
# #
# Files module provides access to files.xml. files.xml is genarated
# during the build process of a package and used in installation.
# Authors: Eray Ozkural <eray@uludag.org.tr> # Authors: Eray Ozkural <eray@uludag.org.tr>
'''Files module provides access to files.xml. files.xml is generated
during the build process of a package and used in installation.'''
import pisi.pxml.autoxml as autoxml import pisi.pxml.autoxml as autoxml
from pisi.util import Checks from pisi.util import Checks
import pisi.lockeddbshelve as shelve import pisi.lockeddbshelve as shelve
class FileInfo: class FileInfo:
"""File holds the information for a File node/tag in files.xml""" """File holds the information for a File node/tag in files.xml"""
@@ -34,6 +35,7 @@ class FileInfo:
self.size, self.hash) self.size, self.hash)
return s return s
class Files(autoxml.XmlFile): class Files(autoxml.XmlFile):
__metaclass__ = autoxml.autoxml __metaclass__ = autoxml.autoxml
@@ -45,30 +47,39 @@ class Files(autoxml.XmlFile):
def append(self, fileinfo): def append(self, fileinfo):
self.list.append(fileinfo) self.list.append(fileinfo)
class FilesDB(shelve.LockedDBShelf): class FilesDB(shelve.LockedDBShelf):
def __init__(self): def __init__(self):
shelve.LockedDBShelf.__init__(self, 'files') shelve.LockedDBShelf.__init__(self, 'files')
def add_files(self, pkg_name, files): def add_files(self, pkg_name, files, txn = None):
for x in files.list: def proc(txn):
self[str(x.path)] = (pkg_name, x) for x in files.list:
self.put(str(x.path), (pkg_name, x), txn)
self.txn_proc(proc, txn)
def remove_files(self, files): def remove_files(self, files, txn = None):
for x in files.list: def proc(txn):
del self[str(x.path)] for x in files.list:
self.delete(str(x.path), txn)
self.txn_proc(proc, txn)
def has_file(self, path): def has_file(self, path, txn = None):
return self.has_key(str(path)) return self.has_key(str(path), txn)
def get_file(self, path): def get_file(self, path, txn = None):
path = str(path) path = str(path)
if not self.has_key(path): def proc(txn):
return None if not self.has_key(path, txn):
else: return None
return self[path] else:
return self.get(path, txn)
return self.txn_proc(proc, txn)
def match_files(self, glob):
# NB: avoid using, this reads the entire db
def get_files(self, glob):
import fnmatch import fnmatch
glob = str(glob) glob = str(glob)