diff -r 3263f36aa50a -r 6893628e22fe trac/db.py
|
a
|
b
|
|
| 24 | 24 | except ImportError: |
| 25 | 25 | import dummy_threading as threading |
| 26 | 26 | threading._get_ident = lambda: 0 |
| | 27 | import weakref |
| 27 | 28 | |
| 28 | 29 | from trac.core import TracError |
| 29 | 30 | |
| … |
… |
|
| 183 | 184 | del self._active[tid] |
| 184 | 185 | if cnx not in self._dormant: |
| 185 | 186 | cnx.rollback() |
| 186 | | self._dormant.append(cnx) |
| | 187 | if cnx.poolable: |
| | 188 | self._dormant.append(cnx) |
| | 189 | else: |
| | 190 | self._cursize -= 1 |
| 187 | 191 | self._available.notify() |
| 188 | 192 | finally: |
| 189 | 193 | self._available.release() |
| … |
… |
|
| 203 | 207 | |
| 204 | 208 | class PyFormatCursor(sqlite.Cursor): |
| 205 | 209 | def execute(self, sql, args=None): |
| 206 | | if args: |
| 207 | | sql = sql % (('?',) * len(args)) |
| 208 | | sqlite.Cursor.execute(self, sql, args or []) |
| | 210 | try: |
| | 211 | if args: |
| | 212 | sql = sql % (('?',) * len(args)) |
| | 213 | sqlite.Cursor.execute(self, sql, args or []) |
| | 214 | except sqlite.OperationalError, e: |
| | 215 | self.cnx.rollback() |
| | 216 | raise e |
| 209 | 217 | def executemany(self, sql, args=None): |
| 210 | | if args: |
| 211 | | sql = sql % (('?',) * len(args[0])) |
| 212 | | sqlite.Cursor.executemany(self, sql, args or []) |
| | 218 | try: |
| | 219 | if args: |
| | 220 | sql = sql % (('?',) * len(args[0])) |
| | 221 | sqlite.Cursor.executemany(self, sql, args or []) |
| | 222 | except sqlite.OperationalError, e: |
| | 223 | self.cnx.rollback() |
| | 224 | raise e |
| 213 | 225 | def _convert_row(self, row): |
| 214 | 226 | return tuple([(isinstance(v, unicode) and [v.encode('utf-8')] or [v])[0] |
| 215 | 227 | for v in row]) |
| … |
… |
|
| 224 | 236 | rows = sqlite.Cursor.fetchall(self) |
| 225 | 237 | return rows != None and [self._convert_row(row) |
| 226 | 238 | for row in rows] or None |
| | 239 | |
| 227 | 240 | |
| 228 | 241 | except ImportError: |
| 229 | 242 | try: |
| … |
… |
|
| 236 | 249 | class SQLiteConnection(ConnectionWrapper): |
| 237 | 250 | """Connection wrapper for SQLite.""" |
| 238 | 251 | |
| 239 | | __slots__ = ['cnx'] |
| | 252 | __slots__ = ['cnx', 'active_cursors'] |
| | 253 | |
| | 254 | poolable = False |
| | 255 | |
| | 256 | poolable = False |
| 240 | 257 | |
| 241 | 258 | def __init__(self, path, params={}): |
| 242 | 259 | assert have_pysqlite > 0 |
| … |
… |
|
| 254 | 271 | 'directory it is located in.' \ |
| 255 | 272 | % (getuser(), path) |
| 256 | 273 | |
| 257 | | timeout = int(params.get('timeout', 10000)) |
| 258 | 274 | if have_pysqlite == 2: |
| | 275 | self.active_cursors = weakref.WeakKeyDictionary() |
| | 276 | timeout = int(params.get('timeout', 10.0)) |
| 259 | 277 | # Convert unicode to UTF-8 bytestrings. This is case-sensitive, so |
| 260 | 278 | # we need two converters |
| 261 | 279 | sqlite.register_converter('text', str) |
| 262 | 280 | sqlite.register_converter('TEXT', str) |
| 263 | 281 | |
| 264 | 282 | cnx = sqlite.connect(path, detect_types=sqlite.PARSE_DECLTYPES, |
| 265 | | check_same_thread=False, timeout=timeout) |
| | 283 | timeout=timeout) |
| 266 | 284 | else: |
| | 285 | timeout = int(params.get('timeout', 10000)) |
| 267 | 286 | cnx = sqlite.connect(path, timeout=timeout) |
| 268 | 287 | ConnectionWrapper.__init__(self, cnx) |
| 269 | 288 | |
| 270 | 289 | if have_pysqlite == 2: |
| 271 | 290 | def cursor(self): |
| 272 | | return self.cnx.cursor(PyFormatCursor) |
| | 291 | cursor = self.cnx.cursor(PyFormatCursor) |
| | 292 | self.active_cursors[cursor] = True |
| | 293 | cursor.cnx = self |
| | 294 | return cursor |
| 273 | 295 | else: |
| 274 | 296 | def cursor(self): |
| 275 | 297 | return self.cnx.cursor() |
| | 298 | |
| | 299 | def _finalize_cursors(self): |
| | 300 | cursors = self.active_cursors.keys() |
| | 301 | for c in cursors: |
| | 302 | c.close() |
| | 303 | |
| | 304 | def rollback(self): |
| | 305 | self._finalize_cursors() |
| | 306 | self.cnx.rollback() |
| 276 | 307 | |
| 277 | 308 | def cast(self, column, type): |
| 278 | 309 | return column |
| … |
… |
|
| 331 | 362 | """Connection wrapper for PostgreSQL.""" |
| 332 | 363 | |
| 333 | 364 | __slots__ = ['cnx'] |
| | 365 | |
| | 366 | poolable = True |
| 334 | 367 | |
| 335 | 368 | def __init__(self, path, user=None, password=None, host=None, port=None, |
| 336 | 369 | params={}): |