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>
--- 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"))