This repository has been archived by the owner on Oct 12, 2017. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Dejavu
158 lines (128 loc) · 5.21 KB
/
Dejavu
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
== Using CherryPy with Dejavu ==
[http://www.aminus.net/dejavu/ Dejavu] is an Object-Relational Mapper library, supporting MySQL, PostgreSQL, SQLite, Microsoft Access, Microsoft SQL Server, shelve, and custom stores. To use it with CherryPy, we create a new sandbox for each request, using a tool which then cleans it up for us automatically:
{{{
#!python
import types
import cherrypy
from cherrypy._cperror import format_exc
def flush_sandbox():
if hasattr(cherrypy.request, "sandbox"):
try:
try:
cherrypy.request.sandbox.flush_all()
except:
cherrypy.log(format_exc(), "DEJAVU")
finally:
del cherrypy.request.sandbox
def try_flush_sandbox():
if cherrypy.response.stream:
# If the body is being streamed, we have to save the data
# *after* the response has been written out
cherrypy.request.hooks.attach('on_end_request', flush_sandbox)
else:
# If the body is not being streamed, we save the data now
if isinstance(cherrypy.response.body, types.GeneratorType):
cherrypy.response.collapse_body()
flush_sandbox()
class SandboxTool(cherrypy.Tool):
def _setup(self):
cherrypy.request.sandbox = arena.new_sandbox()
cherrypy.Tool._setup(self)
cherrypy.tools.sandbox = SandboxTool('on_end_resource', try_flush_sandbox)
}}}
Turn it on and then reference cherrypy.request.sandbox in your page handlers. In your startup script (the one that calls cherrypy.server.start), write:
{{{myapp.arena.load(r"C:\myapp\myappsm.conf")}}}
The filename should be that of a Dejavu configuration file. How's *that* for simple integration? :)
Her's a simple example demonstrating how to use the sandbox in your page handler:
{{{
#!python
import dejavu
from dejavu import Unit, UnitProperty
# global dejavu arena which will handle
# all the dejavu work
arena = dejavu.Arena()
# Creates a specific unit that will handle our messages
# This will have only one single field
# that will be translated into a column
# in the database we'll be using
class Message(Unit):
# Note two things:
# 1. We do not explicitly specify an ID field
# as dejavu does it already
# 2. The property is per-class not per-instance
content = UnitProperty(unicode)
class Root(object):
def __init__(self):
# Purely for this example purpose we enable dejavu's log
# to see what SQL queries dejavu generates
arena.logflags += dejavu.logflags.SQL
arena.logflags += dejavu.logflags.FORGET
# Add a store to the dejavu arena
# The storage we choose is a SQLite in-memory database
# that will disappear once the process exits
arena.add_store("main", "sqlite", {'Database': ":memory:"})
# Inform the arena which unit we will be dealing with
arena.register_all(globals())
# Let's explicitly allocate the space
# in the storage for our unit (i.e. translated into a db table here)
arena.create_storage(Message)
@cherrypy.expose
def index(self):
page = """<html>
<head>
<title>Dejavu sample</title>
</head>
<body>"""
# let's retrieve all existing messages from the storage
messages = cherrypy.request.sandbox.recall(Message)
for message in messages:
# adding them to the HTML code of our page
page = page + '<span style="display:block;">%s</span>' % message.content
# and a way too add new messages
page = page + """
<form action="/save" method="post">
<input type="text" name="message" />
<input type="submit" />
</form>
</body>
</html>
"""
return page
@cherrypy.expose
def save(self, message):
# Let's create a Message instance...
msg = Message(content=message)
# ... that we then tell the sandbox, managed
# by the CherryPy tool, to track.
# The actual storing into the underlying storage
# (i.e. the database INSERT) happens in the
# cherrypy tool
cherrypy.request.sandbox.memorize(msg)
raise cherrypy.HTTPRedirect('/')
if __name__ == '__main__':
conf = {'/': {'tools.sandbox.on': True}}
cherrypy.quickstart(Root(), '/', conf)
}}}
{{{
#!html
<h2 class='compatibility'>Older versions</h2>
}}}
== 2.2 ==
{{{
#!python
class DejavuSandboxFilter(object):
"""Creates and auto-flushes a Dejavu Sandbox for each request."""
def onStartResource(self):
"""Called after the request body has been read/parsed"""
cherrypy.request.sandbox = endue.arena.new_sandbox()
def onEndRequest(self):
"""Called after writing the response (header & body included)"""
if hasattr(cherrypy.request, "sandbox"):
try:
try:
cherrypy.request.sandbox.flush_all()
except:
cherrypy.log(_cputil.formatExc(), "DEJAVU")
finally:
del cherrypy.request.sandbox
}}}