1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 """
18 ==========
19 DB stuff
20 ==========
21
22 DB stuff.
23 """
24 __author__ = u"Andr\xe9 Malo"
25 __docformat__ = "restructuredtext en"
26
27 import sys as _sys
28
29 from wtf import util as _wtf_util
30 from wtf.ext.db import _connection
34 """ Connection wrapper """
35
37 in_transaction = False
38 self.__next_broken = None
39 while isinstance(conn, WTFConnection):
40 dbname = conn.__dbname
41 in_transaction = conn.__in_transaction
42 if not self.__next_broken:
43 self.__next_broken = conn.__mark_broken
44 conn = conn.__conn
45 self.__conn = conn
46 self.__dbname = dbname
47 self.__in_transaction = in_transaction
48 self.__initiated_transaction = False
49 self.__broken = False
51 return getattr(self.__conn, name)
53 if who is None:
54 who = set()
55 if id(self) not in who:
56 who.add(id(self))
57 self.__broken = bool(how)
58 if self.__next_broken:
59 self.__next_broken(how, who)
75
76
77 -def connection(dbname, arg=None, translate_exceptions=True):
78 """
79 Create decorator to inject SA connection into function
80
81 :Parameters:
82 `dbname` : ``str``
83 DB name
84
85 `arg` : ``str``
86 Argument name. If omitted or ``None``, ``'db'`` is used.
87
88 `translate_exceptions` : ``bool``
89 Translate adapter exceptions to our ones?
90
91 :Return: Decorator function
92 :Rtype: ``callable``
93 """
94 if arg is None:
95 arg = 'db'
96 def con(oldval):
97 """ Create connection """
98 if oldval is None:
99 this_con = _connection.connect(dbname)
100 _connection.driver(dbname).autocommit(this_con, True)
101 return True, WTFConnection(dbname, this_con)
102 return False, WTFConnection(dbname, oldval)
103
104 def inner(func):
105 """
106 Actual decorator
107
108 :Parameters:
109 `func` : ``callable``
110 Function to decorate
111
112 :Return: Decorated function
113 :Rtype: ``callable``
114 """
115 setarg = _wtf_util.make_setarg(arg, func)
116
117 @_wtf_util.decorating(func)
118 def proxy(*args, **kwargs):
119 """ Proxy """
120 drv = _connection.driver(dbname)
121 try:
122 (created, opened), args, kwargs = setarg(args, kwargs, con)
123 try:
124 return func(*args, **kwargs)
125 finally:
126 if created:
127 opened.close()
128 except drv.adapter.Error:
129 if translate_exceptions:
130 drv.translate_exception()
131 raise
132 return proxy
133 return inner
134
137 """
138 Create decorator to wrap a connection into a transaction
139
140 :Parameters:
141 `arg` : ``str``
142 Argument name. If omitted or ``None``, ``'db'`` is used.
143
144 :Return: Decorator function
145 :Rtype: ``callable``
146 """
147 if arg is None:
148 func, arg = None, 'db'
149 elif callable(arg):
150 func, arg = arg, 'db'
151 else:
152 func = None
153
154 def make_trans(oldval):
155 """ Create transaction """
156 return False, oldval.begin()
157
158 def inner(func):
159 """
160 Actual decorator
161
162 :Parameters:
163 `func` : ``callable``
164 Function to decorate
165
166 :Return: Decorated function
167 :Rtype: ``callable``
168 """
169 setarg = _wtf_util.make_setarg(arg, func)
170
171 @_wtf_util.decorating(func)
172 def proxy(*args, **kwargs):
173 """ Proxy """
174 (_, trans), args, kwargs = setarg(args, kwargs, make_trans)
175 try:
176 res = func(*args, **kwargs)
177 except:
178 e = _sys.exc_info()
179 try:
180 trans.rollback()
181 finally:
182 try:
183 raise e[0], e[1], e[2]
184 finally:
185 del e
186 trans.commit()
187 return res
188 return proxy
189
190 if func is not None:
191 return inner(func)
192 return inner
193