-
Release v0.9.0 Stable
released this
2026-03-19 07:26:31 -06:00 | 0 commits to main since this releasev0.9.0
code.nochebuena.dev/go/sqliteOverview
sqliteis a pure-Go, CGO-free SQLite client backed bymodernc.org/sqlite. It integrates
with thelauncherlifecycle andhealthcheck systems, serialises write transactions through
a mutex to preventSQLITE_BUSYerrors under concurrent goroutines, and provides a
UnitOfWorkimplementation that injects the active transaction into the context.This is the first stable release. The API was designed through multiple architecture reviews
and validated end-to-end via the todo-api proof-of-concept. It is versioned at v0.9.0 rather
than v1.0.0 because the library has not yet been exercised in production across all edge cases;
the pre-1.0 version preserves the option for minor API refinements without a major bump.What's Included
Executorinterface:ExecContext,QueryContext,QueryRowContextusingdatabase/sql
native types (sql.Result,*sql.Rows,*sql.Row)Txinterface: extendsExecutorwithCommit()/Rollback()— no context arguments,
matching the honestdatabase/sqlcontractClientinterface:GetExecutor(ctx),Begin(ctx),Ping(ctx),HandleError(err)Componentinterface: composeslauncher.Component,health.Checkable, andClientNew(logger, cfg) Componentconstructor; database opened inOnInit, not at constructionConfigstruct with env-tag support (SQLITE_PATH,SQLITE_MAX_OPEN_CONNS,
SQLITE_MAX_IDLE_CONNS,SQLITE_PRAGMAS)- Default Pragmas: WAL journal mode, 5 000 ms busy timeout, foreign key enforcement
(?_journal=WAL&_timeout=5000&_fk=true) PRAGMA foreign_keys = ONenforced explicitly inOnInit; startup fails if the PRAGMA
cannot be setwriteMu sync.MutexinsqliteComponent; acquired byUnitOfWork.Dobefore every write
transaction to preventSQLITE_BUSYUnitOfWorkinterface andNewUnitOfWork(logger, client)constructor using context injectionHandleError(err) errormapping SQLite extended error codes to xerrors:- Code 2067 (SQLITE_CONSTRAINT_UNIQUE) and 1555 (SQLITE_CONSTRAINT_PRIMARYKEY) →
ErrAlreadyExists - Code 787 (SQLITE_CONSTRAINT_FOREIGNKEY) →
ErrInvalidInput sql.ErrNoRows→ErrNotFound- all other errors →
ErrInternal
- Code 2067 (SQLITE_CONSTRAINT_UNIQUE) and 1555 (SQLITE_CONSTRAINT_PRIMARYKEY) →
health.Checkableimplementation athealth.LevelCritical- Pure-Go driver: no CGO, no system libraries; cross-compilation works with
CGO_ENABLED=0
Installation
go get code.nochebuena.dev/go/sqlite@v0.9.0Requires Go 1.21 or later. Depends on
code.nochebuena.dev/go/health,
code.nochebuena.dev/go/launcher,code.nochebuena.dev/go/logz,
code.nochebuena.dev/go/xerrors, andmodernc.org/sqlite.No CGO toolchain is required. Build with
CGO_ENABLED=0without restriction.Design Highlights
Pure-Go driver.
modernc.org/sqliteis used instead ofmattn/go-sqlite3. No CGO, no
system SQLite library required. Binaries are fully self-contained and cross-compile without
a C toolchain.Write serialisation via mutex.
writeMu sync.Mutexis acquired byUnitOfWork.Dobefore
every write transaction. SQLite's single-writer constraint means concurrent write attempts
would otherwise receiveSQLITE_BUSY. The mutex eliminates that race at the application layer.Foreign key enforcement. Enabled in both the default DSN Pragmas (
_fk=true) and via an
explicitPRAGMA foreign_keys = ONinOnInit. SQLite disables foreign keys by default;
both layers ensure enforcement even if Pragmas are overridden.Honest
Txcontract.Tx.Commit()andTx.Rollback()take no context, matching the
database/sqllimitation. The interface documents this explicitly.UnitOfWork via context injection.
GetExecutor(ctx)checks for actxTxKey{}in context.
InsideUnitOfWork.Do, the context carries the active transaction; repositories participate
automatically.Known Limitations & Edge Cases
- Single-writer serialisation limits write throughput. The
writeMumutex means all
write transactions are sequential. This is appropriate for embedded, single-process use
cases; it is not suitable for high-concurrency write workloads. - No migration helper. Schema migrations are out of scope.
:memory:databases are connection-scoped. IfMaxOpenConns > 1, each connection
sees its own in-memory database. For in-memory use, keepMaxOpenConns = 1.- No context on
Tx.Commit()/Tx.Rollback(). A commit or rollback cannot be
cancelled by a deadline or context cancellation. Pragmasoverride replaces defaults entirely. Callers who setConfig.Pragmasmust
include all required pragmas; only the FK PRAGMA inOnInitis guaranteed regardless of
thePragmasfield.
v0.9.0 → v1.0.0 Roadmap
- Evaluate whether read-only queries can bypass the write mutex to allow concurrent reads
while a write transaction is in progress. - Consider a dedicated read connection and a write connection to implement WAL reader/writer
separation at the pool level. - Assess whether
Pragmasshould be a structured type instead of a raw DSN query string. - Gather production feedback on the write mutex approach across real workloads.
Downloads