Ticket #9352: 9352-pysqlite-1.patch
| File 9352-pysqlite-1.patch, 5.7 KB (added by rblank, 21 months ago) |
|---|
-
trac/db/sqlite_backend.py
diff --git a/trac/db/sqlite_backend.py b/trac/db/sqlite_backend.py
a b 35 35 import sqlite3 as sqlite 36 36 have_pysqlite = 2 37 37 except ImportError: 38 have_pysqlite = 0 38 try: 39 import sqlite 40 have_pysqlite = 1 41 except ImportError: 42 have_pysqlite = 0 39 43 40 44 if have_pysqlite == 2: 41 45 # Force values to integers because PySQLite 2.2.0 had (2, 2, '0') … … 102 106 return result 103 107 104 108 109 elif have_pysqlite == 1: 110 sqlite_version = sqlite._sqlite.sqlite_version_info() 111 sqlite_version_string = '%d.%d.%d' % sqlite_version 112 113 class SQLiteUnicodeCursor(sqlite.Cursor): 114 def _convert_row(self, row): 115 return tuple([(isinstance(v, str) and [v.decode('utf-8')] or [v])[0] 116 for v in row]) 117 def fetchone(self): 118 row = sqlite.Cursor.fetchone(self) 119 return row and self._convert_row(row) or None 120 def fetchmany(self, num): 121 rows = sqlite.Cursor.fetchmany(self, num) 122 return rows != None and [self._convert_row(row) 123 for row in rows] or [] 124 def fetchall(self): 125 rows = sqlite.Cursor.fetchall(self) 126 return rows != None and [self._convert_row(row) 127 for row in rows] or [] 128 129 105 130 # Mapping from "abstract" SQL types to DB-specific types 106 131 _type_map = { 107 132 'int': 'integer', … … 152 177 def get_supported_schemes(self): 153 178 if not have_pysqlite: 154 179 self.error = _("Cannot load Python bindings for SQLite") 155 elif sqlite_version >= (3, 3, 3): 156 if sqlite.version_info < (1, 1, 7): 157 self.error = _("Need at least PySqlite %(version)s or higher", 158 version='1.1.7') 159 elif sqlite.version_info[0] == 2 and \ 180 elif sqlite.version_info < (1, 1, 7): 181 self.error = _("Need at least PySqlite %(version)s or higher", 182 version='1.1.7') 183 elif sqlite_version >= (3, 3, 3) and sqlite.version_info[0] == 2 and \ 160 184 sqlite.version_info < (2, 0, 7): 161 self.error = _("Need at least PySqlite %(version)s or higher",162 version='2.0.7')185 self.error = _("Need at least PySqlite %(version)s or higher", 186 version='2.0.7') 163 187 yield ('sqlite', self.error and -1 or 1) 164 188 165 189 def get_connection(self, path, log=None, params={}): … … 254 278 'and the directory it is located in.', 255 279 user=getuser(), path=path)) 256 280 257 self._active_cursors = weakref.WeakKeyDictionary() 258 timeout = int(params.get('timeout', 10.0)) 259 self._eager = params.get('cursor', 'eager') == 'eager' 260 # eager is default, can be turned off by specifying ?cursor= 261 if isinstance(path, unicode): # needed with 2.4.0 262 path = path.encode('utf-8') 263 cnx = sqlite.connect(path, detect_types=sqlite.PARSE_DECLTYPES, 264 check_same_thread=sqlite_version < (3, 3, 1), 265 timeout=timeout) 281 if have_pysqlite == 2: 282 self._active_cursors = weakref.WeakKeyDictionary() 283 timeout = int(params.get('timeout', 10.0)) 284 self._eager = params.get('cursor', 'eager') == 'eager' 285 # eager is default, can be turned off by specifying ?cursor= 286 if isinstance(path, unicode): # needed with 2.4.0 287 path = path.encode('utf-8') 288 cnx = sqlite.connect(path, detect_types=sqlite.PARSE_DECLTYPES, 289 check_same_thread=sqlite_version < (3, 3, 1), 290 timeout=timeout) 291 else: 292 timeout = int(params.get('timeout', 10000)) 293 cnx = sqlite.connect(path, timeout=timeout, encoding='utf-8') 294 266 295 # load extensions 267 296 extensions = params.get('extensions', []) 268 297 if len(extensions) > 0: … … 273 302 274 303 ConnectionWrapper.__init__(self, cnx, log) 275 304 276 def cursor(self): 277 cursor = self.cnx.cursor((PyFormatCursor, EagerCursor)[self._eager]) 278 self._active_cursors[cursor] = True 279 cursor.cnx = self 280 return IterableCursor(cursor, self.log) 305 if have_pysqlite == 2: 306 def cursor(self): 307 cursor = self.cnx.cursor((PyFormatCursor, EagerCursor)[self._eager]) 308 self._active_cursors[cursor] = True 309 cursor.cnx = self 310 return IterableCursor(cursor, self.log) 281 311 282 def rollback(self): 283 for cursor in self._active_cursors.keys(): 284 cursor.close() 285 self.cnx.rollback() 312 def rollback(self): 313 for cursor in self._active_cursors.keys(): 314 cursor.close() 315 self.cnx.rollback() 316 317 else: 318 def cursor(self): 319 self.cnx._checkNotClosed("cursor") 320 cursor = SQLiteUnicodeCursor(self.cnx, self.cnx.rowclass) 321 return IterableCursor(cursor, self.log) 286 322 287 323 def cast(self, column, type): 288 324 if sqlite_version >= (3, 2, 3): … … 313 349 """Return the quoted identifier.""" 314 350 return "`%s`" % identifier 315 351 316 def get_last_id(self, cursor, table, column='id'): 317 return cursor.lastrowid 352 if have_pysqlite == 2: 353 def get_last_id(self, cursor, table, column='id'): 354 return cursor.lastrowid 355 else: 356 def get_last_id(self, cursor, table, column='id'): 357 return self.cnx.db.sqlite_last_insert_rowid()
