diff options
Diffstat (limited to 'openerp/sql_db.py')
| -rw-r--r-- | openerp/sql_db.py | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/openerp/sql_db.py b/openerp/sql_db.py index bd60572d184..749af2376c0 100644 --- a/openerp/sql_db.py +++ b/openerp/sql_db.py @@ -173,6 +173,9 @@ class Cursor(object): self.cache = {} + # event handlers, see method after() below + self._event_handlers = {'commit': [], 'rollback': []} + def __build_dict(self, row): return {d.name: row[i] for i, d in enumerate(self._obj.description)} def dictfetchone(self): @@ -338,16 +341,44 @@ class Cursor(object): self._cnx.set_isolation_level(isolation_level) @check + def after(self, event, func): + """ Register an event handler. + + :param event: the event, either `'commit'` or `'rollback'` + :param func: a callable object, called with no argument after the + event occurs + + Be careful when coding an event handler, since any operation on the + cursor that was just committed/rolled back will take place in the + next transaction that has already begun, and may still be rolled + back or committed independently. You may consider the use of a + dedicated temporary cursor to do some database operation. + """ + self._event_handlers[event].append(func) + + def _pop_event_handlers(self): + # return the current handlers, and reset them on self + result = self._event_handlers + self._event_handlers = {'commit': [], 'rollback': []} + return result + + @check def commit(self): """ Perform an SQL `COMMIT` """ - return self._cnx.commit() + result = self._cnx.commit() + for func in self._pop_event_handlers()['commit']: + func() + return result @check def rollback(self): """ Perform an SQL `ROLLBACK` """ - return self._cnx.rollback() + result = self._cnx.rollback() + for func in self._pop_event_handlers()['rollback']: + func() + return result def __enter__(self): """ Using the cursor as a contextmanager automatically commits and @@ -374,10 +405,11 @@ class Cursor(object): self.execute('SAVEPOINT "%s"' % name) try: yield - self.execute('RELEASE SAVEPOINT "%s"' % name) - except: + except Exception: self.execute('ROLLBACK TO SAVEPOINT "%s"' % name) raise + else: + self.execute('RELEASE SAVEPOINT "%s"' % name) @check def __getattr__(self, name): |
