Skip to content

Commit 0f2dda8

Browse files
committed
Add readonly parameter to Farchive for lock-free reading
- Add readonly=True flag to Farchive.__init__ - In readonly mode: use URI ?mode=ro, skip schema init, no writes - Allows concurrent readers even when writer holds lock - Fixes 'database is locked' errors in consumer projects
1 parent 5dd0e4d commit 0f2dda8

1 file changed

Lines changed: 14 additions & 6 deletions

File tree

src/farchive/_archive.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,21 +110,29 @@ def __init__(
110110
*,
111111
compression: CompressionPolicy | None = None,
112112
enable_events: bool = False,
113+
readonly: bool = False,
113114
):
114115
self._db_path = Path(db_path)
115-
self._db_path.parent.mkdir(parents=True, exist_ok=True)
116116
self._policy = compression or CompressionPolicy()
117+
self._readonly = readonly
117118

118119
# Use default isolation_level ("") for proper transaction support.
119120
# `with self._conn:` gives atomic BEGIN/COMMIT blocks.
120121
# check_same_thread=True enforces the documented "not thread-safe" contract.
121-
self._conn = sqlite3.connect(str(self._db_path))
122+
if readonly:
123+
# Read-only mode: use URI mode to prevent writes
124+
self._conn = sqlite3.connect(f"file:{self._db_path}?mode=ro", uri=True)
125+
else:
126+
self._db_path.parent.mkdir(parents=True, exist_ok=True)
127+
self._conn = sqlite3.connect(str(self._db_path))
128+
122129
self._conn.row_factory = sqlite3.Row
123-
self._conn.execute("PRAGMA journal_mode=WAL")
124-
self._conn.execute("PRAGMA busy_timeout=5000")
125-
self._conn.execute("PRAGMA foreign_keys=ON")
126130

127-
init_schema(self._conn, enable_events=enable_events)
131+
if not readonly:
132+
self._conn.execute("PRAGMA journal_mode=WAL")
133+
self._conn.execute("PRAGMA busy_timeout=5000")
134+
self._conn.execute("PRAGMA foreign_keys=ON")
135+
init_schema(self._conn, enable_events=enable_events)
128136

129137
# Event logging is an archive property: once the event table exists
130138
# (created by any session with enable_events=True), ALL subsequent

0 commit comments

Comments
 (0)