1
2
3
4
5
6
7
8
9 """WSGI middleware for Storm.
10
11 This is the database access inteface for WSGI enabled (PEP 333) web applications.
12
13 Pylons framework example:
14
15 in wsgiapp.py
16
17 from storm.database import create_database
18 from middlestorm import MiddleStorm
19 ...
20
21 # CUSTOM MIDDLEWARE HERE
22 app = MiddleStorm(app, create_database(config['app_conf']['sqlalchemy.default.uri']))
23
24 in controller:
25
26 class DemoController(BaseController):
27 def index(self):
28 store = request.environ['storm.store']
29 ...
30 """
31
32 from storm.database import Database
33 from storm.store import Store
34 from threading import local
35
36 __all__ = ["MiddleStorm"]
37 __author__ = "Vsevolod Balashov <http://vsevolod.balashov.name>"
38 __version__ = "0.1"
39
40 class SingleConn(Database):
41 """Database proxy class.
42 Share single database connection between all Store object instances in threads.
43 If you have readonly database or not use transactions why not?
44 """
45 def __init__(self, database):
46 self._database = database
47 self._connection = database.connect()
48 def connect(self):
49 return self._connection
50
51 class MiddleStorm(object):
52 """WSGI middleware.
53 Add Store object instance in environ['storm.store']. Each thread contains own instance.
54 """
55
56 def __init__(self, app, database, single = False):
57 """Create WSGI middleware.
58 @param app: up level application or middleware.
59 @param database: instance of Database returned create_database.
60 @param: single: use single database connection in all threads.
61 """
62 assert isinstance(database, Database), \
63 'database must be subclass of storm.database.Database'
64 if single:
65 self._database = SingleConn(database)
66 else:
67 self._database = database
68 self._app = app
69 self._local = local()
70
71 def __call__(self, environ, start_response):
72 try:
73 environ['storm.store'] = self._local.store
74 except AttributeError:
75 environ['storm.store'] = \
76 self._local.__dict__.setdefault('store', Store(self._database))
77 return self._app(environ, start_response)