adding after_rollback functionality
This commit is contained in:
@@ -2,7 +2,7 @@ from inspect import getargspec, getmembers, isclass, ismethod
|
|||||||
from util import _cfg
|
from util import _cfg
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'expose', 'transactional', 'accept_noncanonical', 'after_commit'
|
'expose', 'transactional', 'accept_noncanonical', 'after_commit', 'after_rollback'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -105,6 +105,24 @@ def transactional(ignore_redirects=True):
|
|||||||
return deco
|
return deco
|
||||||
|
|
||||||
|
|
||||||
|
def after_action(action_type, action):
|
||||||
|
'''
|
||||||
|
If utilizing the :mod:`pecan.hooks` ``TransactionHook``, allows you
|
||||||
|
to flag a controller method to perform a callable action after the
|
||||||
|
action_type is successfully issued.
|
||||||
|
|
||||||
|
:param action: The callable to call after the commit is successfully issued.
|
||||||
|
'''
|
||||||
|
|
||||||
|
if action_type not in ('commit', 'rollback'):
|
||||||
|
raise Exception, 'action_type (%s) is not valid' % action_type
|
||||||
|
|
||||||
|
|
||||||
|
def deco(func):
|
||||||
|
_cfg(func).setdefault('after_%s' % action_type, []).append(action)
|
||||||
|
return func
|
||||||
|
return deco
|
||||||
|
|
||||||
def after_commit(action):
|
def after_commit(action):
|
||||||
'''
|
'''
|
||||||
If utilizing the :mod:`pecan.hooks` ``TransactionHook``, allows you
|
If utilizing the :mod:`pecan.hooks` ``TransactionHook``, allows you
|
||||||
@@ -113,10 +131,18 @@ def after_commit(action):
|
|||||||
|
|
||||||
:param action: The callable to call after the commit is successfully issued.
|
:param action: The callable to call after the commit is successfully issued.
|
||||||
'''
|
'''
|
||||||
def deco(func):
|
return after_action('commit', action)
|
||||||
_cfg(func).setdefault('after_commit', []).append(action)
|
|
||||||
return func
|
|
||||||
return deco
|
def after_rollback(action):
|
||||||
|
'''
|
||||||
|
If utilizing the :mod:`pecan.hooks` ``TransactionHook``, allows you
|
||||||
|
to flag a controller method to perform a callable action after the
|
||||||
|
rollback is successfully issued.
|
||||||
|
|
||||||
|
:param action: The callable to call after the rollback is successfully issued.
|
||||||
|
'''
|
||||||
|
return after_action('rollback', action)
|
||||||
|
|
||||||
|
|
||||||
def accept_noncanonical(func):
|
def accept_noncanonical(func):
|
||||||
|
|||||||
@@ -156,19 +156,23 @@ class TransactionHook(PecanHook):
|
|||||||
|
|
||||||
def after(self, state):
|
def after(self, state):
|
||||||
if state.request.transactional:
|
if state.request.transactional:
|
||||||
|
action_name = None
|
||||||
if state.request.error:
|
if state.request.error:
|
||||||
|
action_name = 'after_rollback'
|
||||||
self.rollback()
|
self.rollback()
|
||||||
else:
|
else:
|
||||||
|
action_name = 'after_commit'
|
||||||
self.commit()
|
self.commit()
|
||||||
|
|
||||||
#
|
#
|
||||||
# If a controller was routed to, find any
|
# If a controller was routed to, find any
|
||||||
# after_commit actions it may have registered, and perform
|
# after_* actions it may have registered, and perform
|
||||||
# them.
|
# them.
|
||||||
#
|
#
|
||||||
|
if action_name:
|
||||||
controller = getattr(state, 'controller', None)
|
controller = getattr(state, 'controller', None)
|
||||||
if controller is not None:
|
if controller is not None:
|
||||||
actions = _cfg(controller).get('after_commit', [])
|
actions = _cfg(controller).get(action_name, [])
|
||||||
for action in actions:
|
for action in actions:
|
||||||
action()
|
action()
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
from pecan import make_app, expose, request, redirect
|
from pecan import make_app, expose, request, redirect, abort
|
||||||
from pecan.core import state
|
from pecan.core import state
|
||||||
from pecan.hooks import PecanHook, TransactionHook, HookController, RequestViewerHook
|
from pecan.hooks import PecanHook, TransactionHook, HookController, RequestViewerHook
|
||||||
from pecan.configuration import Config
|
from pecan.configuration import Config
|
||||||
from pecan.decorators import transactional, after_commit
|
from pecan.decorators import transactional, after_commit, after_rollback
|
||||||
from copy import copy
|
from copy import copy
|
||||||
from formencode import Schema, validators
|
from formencode import Schema, validators
|
||||||
from webtest import TestApp
|
from webtest import TestApp
|
||||||
@@ -560,6 +560,17 @@ class TestTransactionHook(object):
|
|||||||
run_hook.append('inside')
|
run_hook.append('inside')
|
||||||
return 'Decorated Method!'
|
return 'Decorated Method!'
|
||||||
|
|
||||||
|
@expose()
|
||||||
|
@after_rollback(action('action-three'))
|
||||||
|
def rollback(self):
|
||||||
|
abort(500)
|
||||||
|
|
||||||
|
@expose()
|
||||||
|
@transactional()
|
||||||
|
@after_rollback(action('action-four'))
|
||||||
|
def rollback_decorated(self):
|
||||||
|
abort(500)
|
||||||
|
|
||||||
def gen(event):
|
def gen(event):
|
||||||
return lambda: run_hook.append(event)
|
return lambda: run_hook.append(event)
|
||||||
|
|
||||||
@@ -612,6 +623,39 @@ class TestTransactionHook(object):
|
|||||||
|
|
||||||
run_hook = []
|
run_hook = []
|
||||||
|
|
||||||
|
response = app.get('/rollback', expect_errors=True)
|
||||||
|
assert response.status_int == 500
|
||||||
|
|
||||||
|
assert len(run_hook) == 2
|
||||||
|
assert run_hook[0] == 'start_ro'
|
||||||
|
assert run_hook[1] == 'clear'
|
||||||
|
|
||||||
|
run_hook = []
|
||||||
|
|
||||||
|
response = app.post('/rollback', expect_errors=True)
|
||||||
|
assert response.status_int == 500
|
||||||
|
|
||||||
|
assert len(run_hook) == 4
|
||||||
|
assert run_hook[0] == 'start'
|
||||||
|
assert run_hook[1] == 'rollback'
|
||||||
|
assert run_hook[2] == 'action-three'
|
||||||
|
assert run_hook[3] == 'clear'
|
||||||
|
|
||||||
|
run_hook = []
|
||||||
|
|
||||||
|
response = app.get('/rollback_decorated', expect_errors=True)
|
||||||
|
assert response.status_int == 500
|
||||||
|
|
||||||
|
assert len(run_hook) == 6
|
||||||
|
assert run_hook[0] == 'start_ro'
|
||||||
|
assert run_hook[1] == 'clear'
|
||||||
|
assert run_hook[2] == 'start'
|
||||||
|
assert run_hook[3] == 'rollback'
|
||||||
|
assert run_hook[4] == 'action-four'
|
||||||
|
assert run_hook[5] == 'clear'
|
||||||
|
|
||||||
|
run_hook = []
|
||||||
|
|
||||||
response = app.get('/fourohfour', status=404)
|
response = app.get('/fourohfour', status=404)
|
||||||
assert response.status_int == 404
|
assert response.status_int == 404
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user