Files
sqlite/CHANGELOG.md
Rene Nochebuena bc99d76944 feat(sqlite)!: promote to v1.0.0 — validate write-mutex approach, bump all deps to v1.0.0
All v0.9.0 roadmap items evaluated in production. WAL + write-mutex serialisation validated
under real workloads; no API changes needed. Read/write pool separation and Pragmas structured
type deferred as out-of-scope for this use case tier. Bump all micro-lib dependencies (logz,
health, launcher, xerrors) from v0.9.0 to v1.0.0. API committed as stable.
2026-05-11 19:44:08 -06:00

3.6 KiB

Changelog

All notable changes to this module will be documented in this file.

The format is based on Keep a Changelog, and this module adheres to Semantic Versioning.

1.0.0 — 2026-05-12

Changed

  • All micro-lib dependencies bumped from v0.9.0 to v1.0.0: logz, health, launcher, xerrors.

Unchanged

All existing API (Executor, Tx, Client, Component, UnitOfWork, Config, New, NewUnitOfWork, HandleError) is API-compatible with v0.9.0.

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.ErrNoRowsErrNotFound; 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.