SQLite database file header encoding and decoding.
Every SQLite database file opens with a fixed 100-byte, big-endian header at offset 0 of page 1:
0 7 8 15 16 23 24 31 +--------+--------+--------+--------+ | Magic ("SQLite format 3") | | ... + NUL | +--------+--------+--------+--------+ | Page Size |WrVer |RdVer | +--------+--------+--------+--------+ |Reserved|MaxEPF |MinEPF |LeafPF | +--------+--------+--------+--------+ | File Change Counter | +--------+--------+--------+--------+ | Database Size (pages) | +--------+--------+--------+--------+ | First Freelist Trunk Page | +--------+--------+--------+--------+ | Freelist Page Count | +--------+--------+--------+--------+ | Schema Cookie | +--------+--------+--------+--------+ | Schema Format Number | +--------+--------+--------+--------+ | Default Page Cache Size | +--------+--------+--------+--------+ | Largest Root B-tree Page | +--------+--------+--------+--------+ | Text Encoding | +--------+--------+--------+--------+ | User Version | +--------+--------+--------+--------+ | Incremental Vacuum Mode | +--------+--------+--------+--------+ | Application ID | +--------+--------+--------+--------+ | Reserved for Expansion (20) | | ... | +--------+--------+--------+--------+ | Version-Valid-For Number | +--------+--------+--------+--------+ | SQLite Version Number | +--------+--------+--------+--------+
Every field is big-endian. This module covers the 100-byte header only —
no page layout, B-tree, or record parsing. Those live at deeper offsets
governed by pageSize and are out of scope for v0.0.1.
See the SQLite file format specification for the authoritative field-by-field description.
Round-trip a freshly-created database header
Round-trip a freshly-created database header
import { assertEquals } from "@std/assert"; import { sqliteHeader, SQLITE_HEADER_SIZE, SQLITE_MAGIC, SQLITE_TEXT_ENCODING, } from "@binstruct/sqlite"; const coder = sqliteHeader(); const header = { magic: SQLITE_MAGIC, pageSize: 4096, fileFormatWriteVersion: 1, fileFormatReadVersion: 1, reservedSpacePerPage: 0, maxEmbeddedPayloadFraction: 64, minEmbeddedPayloadFraction: 32, leafPayloadFraction: 32, fileChangeCounter: 1, databaseSizeInPages: 2, firstFreelistTrunkPage: 0, freelistPageCount: 0, schemaCookie: 1, schemaFormatNumber: 4, defaultPageCacheSize: 0, largestRootBtreePage: 0, textEncoding: SQLITE_TEXT_ENCODING.UTF8, userVersion: 0, incrementalVacuumMode: 0, applicationId: 0, reservedForExpansion: new Uint8Array(20), versionValidForNumber: 3045000, sqliteVersionNumber: 3045000, }; const buffer = new Uint8Array(SQLITE_HEADER_SIZE); const written = coder.encode(header, buffer); const [decoded, read] = coder.decode(buffer); assertEquals(written, SQLITE_HEADER_SIZE); assertEquals(read, SQLITE_HEADER_SIZE); assertEquals(decoded, header);