Mercurial > p > roundup > code
comparison roundup/backends/back_sqlite.py @ 7921:e3975f679bf1
issue2551302 - Remove support for sqlite version 1 from back_sqlite.py
Remove sqlite v1 support and document.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Tue, 30 Apr 2024 22:16:22 -0400 |
| parents | e10d0b262abd |
| children | 95f91b6f0386 |
comparison
equal
deleted
inserted
replaced
| 7920:6aa0525187cd | 7921:e3975f679bf1 |
|---|---|
| 36 if sqlite.version_info < (2, 1, 0): | 36 if sqlite.version_info < (2, 1, 0): |
| 37 raise ValueError('pysqlite2 minimum version is 2.1.0+ ' | 37 raise ValueError('pysqlite2 minimum version is 2.1.0+ ' |
| 38 '- %s found' % sqlite.version) | 38 '- %s found' % sqlite.version) |
| 39 sqlite_version = 2 | 39 sqlite_version = 2 |
| 40 except ImportError: | 40 except ImportError: |
| 41 import sqlite | 41 raise ValueError("Unable to import sqlite3 or sqlite 2.") |
| 42 sqlite_version = 1 | |
| 43 | 42 |
| 44 | 43 |
| 45 def db_exists(config): | 44 def db_exists(config): |
| 46 return os.path.exists(os.path.join(config.DATABASE, 'db')) | 45 return os.path.exists(os.path.join(config.DATABASE, 'db')) |
| 47 | 46 |
| 59 identify the database type so it can import the correct indexer | 58 identify the database type so it can import the correct indexer |
| 60 module when using native text search mode. | 59 module when using native text search mode. |
| 61 """ | 60 """ |
| 62 | 61 |
| 63 # char to use for positional arguments | 62 # char to use for positional arguments |
| 64 if sqlite_version in (2, 3): | 63 arg = '?' |
| 65 arg = '?' | |
| 66 else: | |
| 67 arg = '%s' | |
| 68 | 64 |
| 69 dbtype = "sqlite" | 65 dbtype = "sqlite" |
| 70 | 66 |
| 71 # used by some code to switch styles of query | 67 # used by some code to switch styles of query |
| 72 implements_intersect = 1 | 68 implements_intersect = 1 |
| 142 self.Otk = sessions_dbm.OneTimeKeys(self) | 138 self.Otk = sessions_dbm.OneTimeKeys(self) |
| 143 else: | 139 else: |
| 144 self.Otk = sessions_sqlite.OneTimeKeys(self) | 140 self.Otk = sessions_sqlite.OneTimeKeys(self) |
| 145 return self.Otk | 141 return self.Otk |
| 146 | 142 |
| 147 def sqlite_busy_handler(self, data, table, count): | |
| 148 """invoked whenever SQLite tries to access a database that is locked""" | |
| 149 now = time.time() | |
| 150 if count == 1: | |
| 151 # Timeout for handling locked database (default 30s) | |
| 152 self._busy_handler_endtime = now + self.config.RDBMS_SQLITE_TIMEOUT | |
| 153 elif now > self._busy_handler_endtime: | |
| 154 # timeout expired - no more retries | |
| 155 return 0 | |
| 156 # sleep adaptively as retry count grows, | |
| 157 # starting from about half a second | |
| 158 time_to_sleep = 0.01 * (2 << min(5, count)) | |
| 159 time.sleep(time_to_sleep) | |
| 160 return 1 | |
| 161 | |
| 162 def sql_open_connection(self, dbname=None): | 143 def sql_open_connection(self, dbname=None): |
| 163 """Open a standard, non-autocommitting connection. | 144 """Open a standard, non-autocommitting connection. |
| 164 | 145 |
| 165 pysqlite will automatically BEGIN TRANSACTION for us. | 146 pysqlite will automatically BEGIN TRANSACTION for us. |
| 166 """ | 147 """ |
| 172 if dbname: | 153 if dbname: |
| 173 db = os.path.join(self.config.DATABASE, 'db-' + dbname) | 154 db = os.path.join(self.config.DATABASE, 'db-' + dbname) |
| 174 else: | 155 else: |
| 175 db = os.path.join(self.config.DATABASE, 'db') | 156 db = os.path.join(self.config.DATABASE, 'db') |
| 176 logging.getLogger('roundup.hyperdb').info('open database %r' % db) | 157 logging.getLogger('roundup.hyperdb').info('open database %r' % db) |
| 177 # set timeout (30 second default is extraordinarily generous) | 158 conn = sqlite.connect(db, timeout=self.config.RDBMS_SQLITE_TIMEOUT) |
| 178 # for handling locked database | 159 conn.row_factory = sqlite.Row |
| 179 if sqlite_version == 1: | |
| 180 conn = sqlite.connect(db=db) | |
| 181 conn.db.sqlite_busy_handler(self.sqlite_busy_handler) | |
| 182 else: | |
| 183 conn = sqlite.connect(db, timeout=self.config.RDBMS_SQLITE_TIMEOUT) | |
| 184 conn.row_factory = sqlite.Row | |
| 185 | 160 |
| 186 # pysqlite2 / sqlite3 want us to store Unicode in the db but | 161 # pysqlite2 / sqlite3 want us to store Unicode in the db but |
| 187 # that's not what's been done historically and it's definitely | 162 # that's not what's been done historically and it's definitely |
| 188 # not what the other backends do, so we'll stick with UTF-8 | 163 # not what the other backends do, so we'll stick with UTF-8 |
| 189 if sqlite_version in (2, 3): | 164 if sqlite_version in (2, 3): |
| 396 elif sqlite_version in (2, 3): | 371 elif sqlite_version in (2, 3): |
| 397 try: | 372 try: |
| 398 v = entry[name] | 373 v = entry[name] |
| 399 except IndexError: | 374 except IndexError: |
| 400 v = None | 375 v = None |
| 401 elif (sqlite_version == 1 and name in entry): | |
| 402 v = entry[name] | |
| 403 else: | 376 else: |
| 404 v = None | 377 v = None |
| 405 if name == 'id': | 378 if name == 'id': |
| 406 retired_id = v | 379 retired_id = v |
| 407 elif (name == '__retired__' and retired_id and | 380 elif (name == '__retired__' and retired_id and |
| 541 sql = 'insert into ids (name, num) values (%s, %s)' % ( | 514 sql = 'insert into ids (name, num) values (%s, %s)' % ( |
| 542 self.arg, self.arg) | 515 self.arg, self.arg) |
| 543 vals = (spec.classname, 1) | 516 vals = (spec.classname, 1) |
| 544 self.sql(sql, vals) | 517 self.sql(sql, vals) |
| 545 | 518 |
| 546 if sqlite_version in (2, 3): | 519 def load_journal(self, classname, cols, nodeid): |
| 547 def load_journal(self, classname, cols, nodeid): | 520 """We need to turn the sqlite3.Row into a tuple so it can be |
| 548 """We need to turn the sqlite3.Row into a tuple so it can be | |
| 549 unpacked""" | 521 unpacked""" |
| 550 l = rdbms_common.Database.load_journal(self, | 522 l = rdbms_common.Database.load_journal(self, |
| 551 classname, cols, nodeid) | 523 classname, cols, nodeid) |
| 552 cols = range(5) | 524 cols = range(5) |
| 553 return [[row[col] for col in cols] for row in l] | 525 return [[row[col] for col in cols] for row in l] |
| 554 | 526 |
| 555 | 527 |
| 556 class sqliteClass: | 528 class sqliteClass: |
| 557 def filter(self, *args, **kw): | 529 def filter(self, *args, **kw): |
| 558 """ If there's NO matches to a fetch, sqlite returns NULL | 530 """ If there's NO matches to a fetch, sqlite returns NULL |
