Revision 1906
Added by Aaron Marcuse-Kubitza over 12 years ago
lib/sql.py | ||
---|---|---|
145 | 145 |
return row |
146 | 146 |
|
147 | 147 |
def _cache_result(self): |
148 |
if self.query_results != None: # is caching |
|
148 |
is_insert = self._is_insert() |
|
149 |
# For inserts, only cache exceptions since inserts are not |
|
150 |
# idempotent, but an invalid insert will always be invalid |
|
151 |
if self.query_results != None and (not is_insert |
|
152 |
or isinstance(self.result, Exception)): |
|
153 |
|
|
149 | 154 |
assert self.query_lookup != None |
150 | 155 |
self.query_results[self.query_lookup] = (self.query, |
151 |
self.result) |
|
156 |
self.result, self.rowcount) |
|
157 |
|
|
158 |
def _is_insert(self): return self.query.upper().find('INSERT') >= 0 |
|
152 | 159 |
|
153 | 160 |
class CacheCursor: |
154 |
def __init__(self, query, result): |
|
161 |
def __init__(self, query, result, rowcount):
|
|
155 | 162 |
self.query = query |
156 |
if isinstance(result, Exception): raise result |
|
163 |
self.result = result |
|
164 |
self.rowcount = rowcount |
|
165 |
|
|
166 |
def execute(self): |
|
167 |
if isinstance(self.result, Exception): raise self.result |
|
157 | 168 |
# otherwise, result is a rows list |
158 |
self.rowcount = len(result) |
|
159 |
self.iter = iter(result) |
|
169 |
self.iter = iter(self.result) |
|
160 | 170 |
|
161 | 171 |
def fetchone(self): |
162 | 172 |
try: return self.iter.next() |
... | ... | |
168 | 178 |
try: |
169 | 179 |
try: |
170 | 180 |
if not cacheable: raise KeyError |
171 |
actual_query, result = self.query_results[query_lookup]
|
|
181 |
cached_result = self.query_results[query_lookup]
|
|
172 | 182 |
used_cache = True |
173 | 183 |
except KeyError: |
174 | 184 |
cur = self.DbCursor(self, cacheable) |
... | ... | |
176 | 186 |
except Exception, e: |
177 | 187 |
_add_cursor_info(e, cur) |
178 | 188 |
raise |
179 |
else: cur = self.CacheCursor(actual_query, result) |
|
189 |
else: |
|
190 |
cur = self.CacheCursor(*cached_result) |
|
191 |
cur.execute() |
|
180 | 192 |
finally: |
181 | 193 |
if self.log_debug != log_debug_none: # only compute msg if needed |
182 | 194 |
if used_cache: cache_status = 'Cache hit' |
Also available in: Unified diff
sql.py: DbConn: Only cache exceptions for inserts since they are not idempotent, but an invalid insert will always be invalid. If a cached result in an exception, re-raise it in a separate method other than the constructor to ensure that the cursor object is still created, and that its query instance var is set.