Reads a database the C library wrote, decrypting pages in memory, on
modernc's existing read-only VFS. The pager-level blocker that rules out a
read-write VFS does not apply: reading has no WAL frames and no journal
records whose checksums could disagree.
immutable=1 is load-bearing, not decoration. modernc's read-only VFS reports
os.O_RDONLY (0) out of xOpen where SQLite expects SQLITE_OPEN_READONLY (1),
and SQLite decides read-only from exactly that flag (pager.c:5044 ->
btree.c:2640). So mode=ro silently yields a read-WRITE pager, leaving only
that VFS's blanket refusal to open a journal between a caller and its null
xWrite. PRAGMA journal_mode=MEMORY removes the accident and the next write
SIGSEGVs the process -- reproduced, and now a regression test. immutable=1
routes through pager.c:5081, where readOnly comes from vfsFlags rather than
from the VFS, so the pager really is read-only and writes are refused before
any journal or page write. It cannot be turned off from SQL, unlike PRAGMA
query_only.
Read-only is proven at open, not assumed: Open runs a write and refuses to
return a handle if it succeeds.
Open also refuses a database with a non-empty -wal or -journal beside it.
Either may hold committed data not yet in the main file, or uncommitted data
that must come out of it, and whether a WAL is checkpointed cannot be settled
from the file alone. Answering anyway would mean stale numbers off a ledger.
A wrong key is an error at open, not corruption later.