|
1 | 1 |
|
| 2 | +import os |
2 | 3 | import sys |
3 | 4 | import time |
4 | 5 | import sqlite3 |
@@ -69,22 +70,34 @@ def _wal_throttled(self): |
69 | 70 |
|
70 | 71 | def _db_connect(self): |
71 | 72 | CID = SQLite3Backend._getCID() |
72 | | - # PARSE_DECLTYPES is active so certain data types (such as datetime) will not be BLOBs |
73 | 73 | assert CID not in self._conn |
74 | | - self._conn[CID] = sqlite3.connect( |
75 | | - self._sqlFile, |
76 | | - detect_types = sqlite3.PARSE_DECLTYPES, |
77 | | - check_same_thread = False |
78 | | - ) |
79 | 74 | if SQLite3Backend.PY2: |
80 | | - self._conn[CID].text_factory = bytes |
| 75 | + self._db_connect_py2(CID) |
| 76 | + else: |
| 77 | + self._conn[CID] = sqlite3.connect( |
| 78 | + 'file:{:s}?immutable={:s}'.format(self._sqlFile, '1' if self.readonly else '0'), |
| 79 | + detect_types = sqlite3.PARSE_DECLTYPES, # so datetimes won't be BLOBs |
| 80 | + check_same_thread = False, |
| 81 | + uri = True, |
| 82 | + ) |
81 | 83 | c = self._get_conn().cursor() |
82 | 84 | if self.readonly is True: |
83 | 85 | c.execute('PRAGMA query_only=1') |
84 | 86 | else: |
85 | 87 | c.execute('PRAGMA journal_mode=WAL') |
86 | 88 | c.execute('PRAGMA synchronous=NORMAL') |
87 | 89 |
|
| 90 | + # Legacy support for Python<3.x. |
| 91 | + def _db_connect_py2(self, CID): |
| 92 | + if os.access(self._sqlFile, os.W_OK) is False: |
| 93 | + raise Exception('Python>=3.x is required for immutable sqlite3 database.') |
| 94 | + self._conn[CID] = sqlite3.connect( |
| 95 | + self._sqlFile, |
| 96 | + detect_types = sqlite3.PARSE_DECLTYPES, |
| 97 | + check_same_thread = False |
| 98 | + ) |
| 99 | + self._conn[CID].text_factory = bytes |
| 100 | + |
88 | 101 | def _db_disconnect(self): |
89 | 102 | # Commit, checkpoint. |
90 | 103 | if self.readonly is False: |
|
0 commit comments