summaryrefslogtreecommitdiff
path: root/openerp/sql_db.py
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2016-01-27 12:24:04 +0100
committerChristophe Simonis <chs@odoo.com>2016-01-27 12:24:04 +0100
commit78d20b552b4374b94aec7097c0e6a48a3dd2d961 (patch)
tree5acd7cbf1cc9e2f277034f44fc0ebebaa3a1a79c /openerp/sql_db.py
parent740a6eadd379cc3fa26aefb9350f1c95b3e05ebd (diff)
parent7e44ddcda3f21c7e6401173539dc0fe93f9a7dd2 (diff)
[MERGE] forward port of branch saas-8 up to 7e44ddc
Diffstat (limited to 'openerp/sql_db.py')
-rw-r--r--openerp/sql_db.py40
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):