"""WSGI middleware for Storm.
This is the database access inteface for WSGI enabled (PEP 333) web applications.
Pylons framework example:
in wsgiapp.py
from storm.database import create_database
from middlestorm import MiddleStorm
...
# CUSTOM MIDDLEWARE HERE
app = MiddleStorm(app, create_database(config['app_conf']['sqlalchemy.default.uri']))
in controller:
class DemoController(BaseController):
def index(self):
store = request.environ['storm.store']
...
"""
from storm.database import Database
from storm.store import Store
from threading import local
__all__ = ["MiddleStorm"]
__author__ = "Vsevolod Balashov <http://vsevolod.balashov.name>"
__version__ = "0.1"
class SingleConn(Database):
"""Database proxy class.
Share single database connection between all Store object instances in threads.
If you have readonly database or not use transactions why not?
"""
def __init__(self, database):
self._database = database
self._connection = database.connect()
def connect(self):
return self._connection
class MiddleStorm(object):
"""WSGI middleware.
Add Store object instance in environ['storm.store']. Each thread contains own instance.
"""
def __init__(self, app, database, single = False):
"""Create WSGI middleware.
@param app: up level application or middleware.
@param database: instance of Database returned create_database.
@param: single: use single database connection in all threads.
"""
assert isinstance(database, Database), \
'database must be subclass of storm.database.Database'
if single:
self._database = SingleConn(database)
else:
self._database = database
self._app = app
self._local = local()
def __call__(self, environ, start_response):
try:
environ['storm.store'] = self._local.store
except AttributeError:
environ['storm.store'] = \
self._local.__dict__.setdefault('store', Store(self._database))
return self._app(environ, start_response)