-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathwsgi_middleware.py
More file actions
109 lines (89 loc) · 3.47 KB
/
wsgi_middleware.py
File metadata and controls
109 lines (89 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import sys
import sqlobject
from sqlobject.compat import string_type
# The module was imported during documentation building
if 'sphinx' not in sys.modules:
from paste.deploy.converters import asbool
from paste.wsgilib import catch_errors
from paste.util import import_string
def make_middleware(app, global_conf, database=None, use_transaction=False,
hub=None):
"""
WSGI middleware that sets the connection for the request (using
the database URI or connection object) and the given hub (or
``sqlobject.sqlhub`` if not given).
If ``use_transaction`` is true, then the request will be run in a
transaction.
Applications can use the keys (which are all no-argument functions):
``sqlobject.get_connection()``:
Returns the connection object
``sqlobject.abort()``:
Aborts the transaction. Does not raise an error, but at the *end*
of the request there will be a rollback.
``sqlobject.begin()``:
Starts a transaction. First commits (or rolls back if aborted) if
this is run in a transaction.
``sqlobject.in_transaction()``:
Returns true or false, depending if we are currently in a
transaction.
"""
use_transaction = asbool(use_transaction)
if database is None:
database = global_conf.get('database')
if not database:
raise ValueError(
"You must provide a 'database' configuration value")
if isinstance(hub, string_type):
hub = import_string.eval_import(hub)
if not hub:
hub = sqlobject.sqlhub
if isinstance(database, string_type):
database = sqlobject.connectionForURI(database)
return SQLObjectMiddleware(app, database, use_transaction, hub)
class SQLObjectMiddleware(object):
def __init__(self, app, conn, use_transaction, hub):
self.app = app
self.conn = conn
self.use_transaction = use_transaction
self.hub = hub
def __call__(self, environ, start_response):
conn = [self.conn]
if self.use_transaction:
conn[0] = conn[0].transaction()
any_errors = []
use_transaction = [self.use_transaction]
self.hub.threadConnection = conn[0]
def abort():
assert use_transaction[0], (
"You cannot abort, because a transaction is not being used")
any_errors.append(None)
def begin():
if use_transaction[0]:
if any_errors:
conn[0].rollback()
else:
conn[0].commit()
any_errors[:] = []
use_transaction[0] = True
conn[0] = self.conn.transaction()
self.hub.threadConnection = conn[0]
def error(exc_info=None):
any_errors.append(None)
ok()
def ok():
if use_transaction[0]:
if any_errors:
conn[0].rollback()
else:
conn[0].commit(close=True)
self.hub.threadConnection = None
def in_transaction():
return use_transaction[0]
def get_connection():
return conn[0]
environ['sqlobject.get_connection'] = get_connection
environ['sqlobject.abort'] = abort
environ['sqlobject.begin'] = begin
environ['sqlobject.in_transaction'] = in_transaction
return catch_errors(self.app, environ, start_response,
error_callback=error, ok_callback=ok)