mercurial/transaction.py
changeset 8289 fe8a3e56039f
parent 8225 46293a0c7e9f
child 8290 560af1bbfd6e
equal deleted inserted replaced
8288:9de088320e9a 8289:fe8a3e56039f
    11 # This software may be used and distributed according to the terms of the
    11 # This software may be used and distributed according to the terms of the
    12 # GNU General Public License version 2, incorporated herein by reference.
    12 # GNU General Public License version 2, incorporated herein by reference.
    13 
    13 
    14 from i18n import _
    14 from i18n import _
    15 import os, errno
    15 import os, errno
       
    16 import error
       
    17 
       
    18 def active(func):
       
    19     def _active(self, *args, **kwds):
       
    20         if self.count == 0:
       
    21             raise error.Abort(_(
       
    22                 'cannot use transaction when it is already committed/aborted'))
       
    23         return func(self, *args, **kwds)
       
    24     return _active
    16 
    25 
    17 class transaction(object):
    26 class transaction(object):
    18     def __init__(self, report, opener, journal, after=None, createmode=None):
    27     def __init__(self, report, opener, journal, after=None, createmode=None):
    19         self.journal = None
    28         self.journal = None
    20 
    29 
    30         if createmode is not None:
    39         if createmode is not None:
    31             os.chmod(self.journal, createmode & 0666)
    40             os.chmod(self.journal, createmode & 0666)
    32 
    41 
    33     def __del__(self):
    42     def __del__(self):
    34         if self.journal:
    43         if self.journal:
    35             if self.entries: self.abort()
    44             if self.entries: self._abort()
    36             self.file.close()
    45             self.file.close()
    37 
    46 
       
    47     @active
    38     def add(self, file, offset, data=None):
    48     def add(self, file, offset, data=None):
    39         if file in self.map: return
    49         if file in self.map: return
    40         self.entries.append((file, offset, data))
    50         self.entries.append((file, offset, data))
    41         self.map[file] = len(self.entries) - 1
    51         self.map[file] = len(self.entries) - 1
    42         # add enough data to the journal to do the truncate
    52         # add enough data to the journal to do the truncate
    43         self.file.write("%s\0%d\n" % (file, offset))
    53         self.file.write("%s\0%d\n" % (file, offset))
    44         self.file.flush()
    54         self.file.flush()
    45 
    55 
       
    56     @active
    46     def find(self, file):
    57     def find(self, file):
    47         if file in self.map:
    58         if file in self.map:
    48             return self.entries[self.map[file]]
    59             return self.entries[self.map[file]]
    49         return None
    60         return None
    50 
    61 
       
    62     @active
    51     def replace(self, file, offset, data=None):
    63     def replace(self, file, offset, data=None):
    52         if file not in self.map:
    64         if file not in self.map:
    53             raise KeyError(file)
    65             raise KeyError(file)
    54         index = self.map[file]
    66         index = self.map[file]
    55         self.entries[index] = (file, offset, data)
    67         self.entries[index] = (file, offset, data)
    56         self.file.write("%s\0%d\n" % (file, offset))
    68         self.file.write("%s\0%d\n" % (file, offset))
    57         self.file.flush()
    69         self.file.flush()
    58 
    70 
       
    71     @active
    59     def nest(self):
    72     def nest(self):
    60         self.count += 1
    73         self.count += 1
    61         return self
    74         return self
    62 
    75 
    63     def running(self):
    76     def running(self):
    64         return self.count > 0
    77         return self.count > 0
    65 
    78 
       
    79     @active
    66     def close(self):
    80     def close(self):
    67         self.count -= 1
    81         self.count -= 1
    68         if self.count != 0:
    82         if self.count != 0:
    69             return
    83             return
    70         self.file.close()
    84         self.file.close()
    73             self.after()
    87             self.after()
    74         else:
    88         else:
    75             os.unlink(self.journal)
    89             os.unlink(self.journal)
    76         self.journal = None
    90         self.journal = None
    77 
    91 
       
    92     @active
    78     def abort(self):
    93     def abort(self):
       
    94         self._abort()
       
    95 
       
    96     def _abort(self):
    79         if not self.entries: return
    97         if not self.entries: return
    80 
    98 
    81         self.report(_("transaction abort!\n"))
    99         self.report(_("transaction abort!\n"))
    82 
   100 
    83         failed = False
   101         failed = False