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