94 self.backupsfile = opener.open(self.backupjournal, 'w') |
94 self.backupsfile = opener.open(self.backupjournal, 'w') |
95 if createmode is not None: |
95 if createmode is not None: |
96 opener.chmod(self.journal, createmode & 0666) |
96 opener.chmod(self.journal, createmode & 0666) |
97 opener.chmod(self.backupjournal, createmode & 0666) |
97 opener.chmod(self.backupjournal, createmode & 0666) |
98 |
98 |
|
99 # hold file generations to be performed on commit |
|
100 self._filegenerators = {} |
|
101 |
99 def __del__(self): |
102 def __del__(self): |
100 if self.journal: |
103 if self.journal: |
101 self._abort() |
104 self._abort() |
102 |
105 |
103 @active |
106 @active |
171 self.backupmap[file] = len(self.backupentries) - 1 |
174 self.backupmap[file] = len(self.backupentries) - 1 |
172 self.backupsfile.write("%s\0%s\0" % (file, backupfile)) |
175 self.backupsfile.write("%s\0%s\0" % (file, backupfile)) |
173 self.backupsfile.flush() |
176 self.backupsfile.flush() |
174 |
177 |
175 @active |
178 @active |
|
179 def addfilegenerator(self, genid, filenames, genfunc, order=0): |
|
180 """add a function to generates some files at transaction commit |
|
181 |
|
182 The `genfunc` argument is a function capable of generating proper |
|
183 content of each entry in the `filename` tuple. |
|
184 |
|
185 At transaction close time, `genfunc` will be called with one file |
|
186 object argument per entries in `filenames`. |
|
187 |
|
188 The transaction itself is responsible for the backup, creation and |
|
189 final write of such file. |
|
190 |
|
191 The `genid` argument is used to ensure the same set of file is only |
|
192 generated once. Call to `addfilegenerator` for a `genid` already |
|
193 present will overwrite the old entry. |
|
194 |
|
195 The `order` argument may be used to control the order in which multiple |
|
196 generator will be executed. |
|
197 """ |
|
198 self._filegenerators[genid] = (order, filenames, genfunc) |
|
199 |
|
200 @active |
176 def find(self, file): |
201 def find(self, file): |
177 if file in self.map: |
202 if file in self.map: |
178 return self.entries[self.map[file]] |
203 return self.entries[self.map[file]] |
179 if file in self.backupmap: |
204 if file in self.backupmap: |
180 return self.backupentries[self.backupmap[file]] |
205 return self.backupentries[self.backupmap[file]] |
211 return self.count > 0 |
236 return self.count > 0 |
212 |
237 |
213 @active |
238 @active |
214 def close(self): |
239 def close(self): |
215 '''commit the transaction''' |
240 '''commit the transaction''' |
|
241 # write files registered for generation |
|
242 for order, filenames, genfunc in sorted(self._filegenerators.values()): |
|
243 files = [] |
|
244 try: |
|
245 for name in filenames: |
|
246 self.addbackup(name) |
|
247 files.append(self.opener(name, 'w', atomictemp=True)) |
|
248 genfunc(*files) |
|
249 finally: |
|
250 for f in files: |
|
251 f.close() |
|
252 |
216 if self.count == 1 and self.onclose is not None: |
253 if self.count == 1 and self.onclose is not None: |
217 self.onclose() |
254 self.onclose() |
218 |
255 |
219 self.count -= 1 |
256 self.count -= 1 |
220 if self.count != 0: |
257 if self.count != 0: |