pub struct Pager { /* private fields */ }Implementations§
Source§impl Pager
impl Pager
Sourcepub fn open(path: &Path) -> Result<Self>
pub fn open(path: &Path) -> Result<Self>
Opens an existing database file for read-write access. Shorthand
for Pager::open_with_mode with AccessMode::ReadWrite.
Sourcepub fn open_read_only(path: &Path) -> Result<Self>
pub fn open_read_only(path: &Path) -> Result<Self>
Opens an existing database file for read-only access — takes
a shared advisory lock that coexists with other readers but is
excluded by any writer. commit and checkpoint return a clean
error rather than panic; stage_page stays a no-op-to-disk
(bytes sit in the in-memory staged map that commit would
have drained).
If the WAL sidecar doesn’t exist, the open succeeds with an
empty wal_cache — a read-only caller can’t materialize a
sidecar on its own, and a DB that never had WAL writes is fine
to read straight from the main file.
Sourcepub fn open_with_mode(path: &Path, mode: AccessMode) -> Result<Self>
pub fn open_with_mode(path: &Path, mode: AccessMode) -> Result<Self>
Opens an existing database file with the given access mode.
Loads every main-file page into on_disk, then opens the WAL
sidecar (read-only mode uses a shared lock and skips sidecar
creation; read-write creates the sidecar if missing) and layers
committed frames into wal_cache.
Sourcepub fn create(path: &Path) -> Result<Self>
pub fn create(path: &Path) -> Result<Self>
Creates a fresh database file. Page 0 is the header; page 1 is an
empty TableLeaf that serves as the initial sqlrite_master root
(zero rows, no user tables yet). A matching empty WAL sidecar is
created alongside it — any pre-existing WAL at the target path is
truncated.
pub fn header(&self) -> DbHeader
Sourcepub fn access_mode(&self) -> AccessMode
pub fn access_mode(&self) -> AccessMode
Returns the mode this Pager was opened in. Callers can use this to bail out of a write path earlier than the Pager itself would.
Sourcepub fn read_page(&self, page_num: u32) -> Option<&[u8; 4096]>
pub fn read_page(&self, page_num: u32) -> Option<&[u8; 4096]>
Reads a page, preferring staged content, then the WAL-committed
overlay, then the frozen main-file snapshot. Returns None for
pages beyond the current page count (pages that have been logically
truncated by a shrink-commit stay in on_disk until checkpoint,
but a bounds check hides them from readers).
Sourcepub fn stage_page(&mut self, page_num: u32, bytes: [u8; 4096])
pub fn stage_page(&mut self, page_num: u32, bytes: [u8; 4096])
Queues bytes as the new content of page page_num. The write only
reaches disk when commit is called.
Sourcepub fn clear_staged(&mut self)
pub fn clear_staged(&mut self)
Discards all staged pages. Useful when beginning a new full re-save
from scratch; the higher layer can also just overwrite pages without
clearing since stage_page replaces.
Sourcepub fn commit(&mut self, new_header: DbHeader) -> Result<usize>
pub fn commit(&mut self, new_header: DbHeader) -> Result<usize>
Commits all staged pages into the WAL. Only pages whose bytes differ from the effective committed state (wal_cache layered on on_disk) produce frames. A final commit frame carries the new page 0 (encoded header) and is fsync’d; that seals the transaction. The main file is left untouched — it only changes when the checkpointer (Phase 4d) runs.
Returns the number of dirty data frames appended (excluding the implicit page-0 commit frame that’s always written).
Sourcepub fn checkpoint(&mut self) -> Result<usize>
pub fn checkpoint(&mut self) -> Result<usize>
Folds all WAL-resident pages back into the main file and truncates the WAL. Returns the number of data pages written to the main file (excludes the header).
Crash safety — two fsync barriers. The main-file writes happen in two phases separated by a barrier, matching SQLite’s checkpoint ordering:
- Write every
wal_cachedata page at itspage_num * PAGE_SIZEoffset in the main file. fsync— force those data pages to stable storage before the header publishes the new state. Without this barrier, a filesystem or disk-cache reordering could land the header first, leaving a main file that claims “N pages” over stale data.- Rewrite the main-file header at offset 0. This is the checkpoint’s “commit point” — after it hits disk the main file alone tells the truth.
set_lenshrinks the tail ifpage_countdropped.fsync— force the header + set_len durable.Wal::truncateresets the sidecar (rolls salt, writes new header, fsync). Running this after the main file is fully durable means a crash between 5 and 6 leaves a stale WAL over a current main file; readers still see the right bytes because wal_cache (replayed from the stale WAL on next open) would be byte-identical to what’s in the main file. A retry ofcheckpointthen truncates cleanly.
A crash between 1 and 2 can leave partial data-page writes, but since the header hasn’t moved yet, the main file still reads as its pre-checkpoint self — the WAL is intact and authoritative, and a retry rewrites the same bytes.