From cce8e45eb97ec67d28a0fe2e994d635a3150e9e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eray=20=C3=96zkural?= Date: Thu, 8 Dec 2005 15:18:55 +0000 Subject: [PATCH] * 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! --- pisi/cli/commands.py | 15 +++++++++----- pisi/dbshelve.py | 43 +++++++++++++++++++++++++--------------- pisi/files.py | 47 +++++++++++++++++++++++++++----------------- 3 files changed, 66 insertions(+), 39 deletions(-) diff --git a/pisi/cli/commands.py b/pisi/cli/commands.py index 13a1538c..75d9375f 100644 --- a/pisi/cli/commands.py +++ b/pisi/cli/commands.py @@ -712,6 +712,8 @@ Usage: add-repo : name of repository to add : 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 """ __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): - if len(self.args)>=2: + if len(self.args)==2 or len(self.args)==0: self.init() - name = self.args[0] - indexuri = self.args[1] + if len(self.args)==2: + 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) if ctx.ui.confirm(_('Update PISI database for repository %s?') % 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)) else: #FIXME: this linear search thing is not working well -- exa - files = ctx.filesdb.get_files(path) + files = ctx.filesdb.match_files(path) if 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)) if ctx.config.options.long: ctx.ui.info(_('Type: %s, Hash: %s') % (file_info.type, diff --git a/pisi/dbshelve.py b/pisi/dbshelve.py index f3d14529..5720e533 100644 --- a/pisi/dbshelve.py +++ b/pisi/dbshelve.py @@ -46,25 +46,36 @@ class DBShelf: #def __del__(self): # self.close() - def has_key(self, key): - return self.db.has_key(key) - - 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() + def has_key(self, key, txn = None): + if txn: + return self.db.has_key(key, txn) 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): - del self[x] + self.delete(txn) + txn_proc(proc, txn) - #def delete(self, txn = None): - # self.db.delete(self, txn + def delete(self, txn): + def proc(txn): + self.db.delete(txn) + txn_proc(proc, txn) # another lame pythonic implementation method: #def __getattr__(self, name): diff --git a/pisi/files.py b/pisi/files.py index f0b912e8..321f0f26 100644 --- a/pisi/files.py +++ b/pisi/files.py @@ -9,16 +9,17 @@ # # 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 +'''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 from pisi.util import Checks import pisi.lockeddbshelve as shelve + class FileInfo: """File holds the information for a File node/tag in files.xml""" @@ -34,6 +35,7 @@ class FileInfo: self.size, self.hash) return s + class Files(autoxml.XmlFile): __metaclass__ = autoxml.autoxml @@ -45,30 +47,39 @@ class Files(autoxml.XmlFile): def append(self, fileinfo): self.list.append(fileinfo) + class FilesDB(shelve.LockedDBShelf): def __init__(self): shelve.LockedDBShelf.__init__(self, 'files') - def add_files(self, pkg_name, files): - for x in files.list: - self[str(x.path)] = (pkg_name, x) + def add_files(self, pkg_name, files, txn = None): + def proc(txn): + for x in files.list: + self.put(str(x.path), (pkg_name, x), txn) + self.txn_proc(proc, txn) - def remove_files(self, files): - for x in files.list: - del self[str(x.path)] + def remove_files(self, files, txn = None): + def proc(txn): + for x in files.list: + self.delete(str(x.path), txn) + self.txn_proc(proc, txn) - def has_file(self, path): - return self.has_key(str(path)) + def has_file(self, path, txn = None): + return self.has_key(str(path), txn) - def get_file(self, path): + def get_file(self, path, txn = None): path = str(path) - if not self.has_key(path): - return None - else: - return self[path] + def proc(txn): + if not self.has_key(path, txn): + return None + 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 glob = str(glob)