# Changelog All notable changes to this module will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this module adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [0.9.0] - 2026-03-18 ### Added - `Executor` interface: `ExecContext`, `QueryContext`, `QueryRowContext` using `database/sql` types (`sql.Result`, `*sql.Rows`, `*sql.Row`). - `Tx` interface: embeds `Executor` and adds `Commit() error` and `Rollback() error` (no context argument, matching `database/sql` semantics). - `Client` interface: `GetExecutor(ctx context.Context) Executor`, `Begin(ctx context.Context) (Tx, error)`, `Ping(ctx context.Context) error`, `HandleError(err error) error`. - `Component` interface: composes `launcher.Component`, `health.Checkable`, and `Client`. - `UnitOfWork` interface: `Do(ctx context.Context, fn func(ctx context.Context) error) error`. - `Config` struct: fields `Path` (`SQLITE_PATH`), `MaxOpenConns` (default `1`), `MaxIdleConns` (default `1`), `Pragmas` (default `?_journal=WAL&_timeout=5000&_fk=true`); settable via `SQLITE_*` environment variables. - `New(logger logz.Logger, cfg Config) Component`: returns a pure-Go SQLite component backed by `modernc.org/sqlite`; no CGO required. - Lifecycle hooks: `OnInit` opens the database, sets connection limits, and enforces `PRAGMA foreign_keys = ON`; startup fails if the pragma cannot be set. `OnStart` pings with a 5-second timeout. `OnStop` closes the connection. - `health.Checkable` implementation: `HealthCheck` delegates to `Ping`; `Name()` returns `"sqlite"`; `Priority()` returns `health.LevelCritical`. - `NewUnitOfWork(logger logz.Logger, client Client) UnitOfWork`: wraps a `Client` to provide transactional `Do` semantics. When the client is the concrete `*sqliteComponent`, the write mutex is acquired for the duration of `Do` to serialise concurrent write transactions and prevent `SQLITE_BUSY`. - `HandleError(err error) error` (package-level function): maps SQLite extended error codes via a duck-typed `coder` interface — code `2067` (unique constraint) and `1555` (primary key constraint) → `ErrAlreadyExists`; code `787` (foreign key constraint) → `ErrInvalidInput`; `sql.ErrNoRows` → `ErrNotFound`; all others → `ErrInternal`. - Transaction context injection: the active `*sql.Tx` is stored under an unexported `ctxTxKey{}` context key; `GetExecutor` returns it when found, otherwise returns `*sql.DB`. - WAL journal mode, 5-second busy timeout, and foreign key enforcement enabled by default via the `Pragmas` DSN suffix. - Support for in-memory databases via `Config{Path: ":memory:"}` for test isolation. ### Design Notes - `modernc.org/sqlite` (pure Go, no CGO) is used instead of `mattn/go-sqlite3`, enabling cross-compilation with `CGO_ENABLED=0` and no system library dependency. - A `sync.Mutex` (`writeMu`) on the component serialises all `UnitOfWork.Do` calls, preventing `SQLITE_BUSY` errors that arise from SQLite's single-writer constraint without requiring callers to manage locking. - Foreign key enforcement is applied both via the `_fk=true` DSN pragma and an explicit `PRAGMA foreign_keys = ON` statement in `OnInit`, ensuring enforcement is active regardless of driver-level pragma handling. [0.9.0]: https://com.nochebuena.dev/go/sqlite/releases/tag/v0.9.0