Mercurial > hg
changeset 8289:fe8a3e56039f
transaction: ensure finished transactions are not reused
All transactional methods on the transaction class have had a decorator
added that ensures the transaction is running.
Co-contributor: Sune Foldager <cryo@cyanite.org>
author | Henrik Stuart <hg@hstuart.dk> |
---|---|
date | Fri, 24 Apr 2009 09:56:53 +0200 |
parents | 9de088320e9a |
children | 560af1bbfd6e |
files | mercurial/transaction.py |
diffstat | 1 files changed, 19 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/transaction.py Mon May 04 03:49:57 2009 +0200 +++ b/mercurial/transaction.py Fri Apr 24 09:56:53 2009 +0200 @@ -13,6 +13,15 @@ from i18n import _ import os, errno +import error + +def active(func): + def _active(self, *args, **kwds): + if self.count == 0: + raise error.Abort(_( + 'cannot use transaction when it is already committed/aborted')) + return func(self, *args, **kwds) + return _active class transaction(object): def __init__(self, report, opener, journal, after=None, createmode=None): @@ -32,9 +41,10 @@ def __del__(self): if self.journal: - if self.entries: self.abort() + if self.entries: self._abort() self.file.close() + @active def add(self, file, offset, data=None): if file in self.map: return self.entries.append((file, offset, data)) @@ -43,11 +53,13 @@ self.file.write("%s\0%d\n" % (file, offset)) self.file.flush() + @active def find(self, file): if file in self.map: return self.entries[self.map[file]] return None + @active def replace(self, file, offset, data=None): if file not in self.map: raise KeyError(file) @@ -56,6 +68,7 @@ self.file.write("%s\0%d\n" % (file, offset)) self.file.flush() + @active def nest(self): self.count += 1 return self @@ -63,6 +76,7 @@ def running(self): return self.count > 0 + @active def close(self): self.count -= 1 if self.count != 0: @@ -75,7 +89,11 @@ os.unlink(self.journal) self.journal = None + @active def abort(self): + self._abort() + + def _abort(self): if not self.entries: return self.report(_("transaction abort!\n"))