-
Release v0.9.1 Stable
released this
2026-03-20 14:16:15 -06:00 | 0 commits to main since this releasev0.9.1
code.nochebuena.dev/go/mysqlOverview
Patch release that resolves the
parseTime,loc, andcharsethardcoded-DSN limitation
documented in v0.9.0. Three new optionalConfigfields expose those parameters as
first-class configuration. All interfaces are unchanged; existing code requires no
modifications.What's New
Configurable DSN parameters
Configgains three new optional string fields:Field Env var Default Description CharsetMYSQL_CHARSET"utf8mb4"Connection character set ( SET NAMES <charset>)LocMYSQL_LOC"UTC"IANA timezone for time.Time↔DATETIMEconversionParseTimeMYSQL_PARSE_TIME"true"Driver-level DATE/DATETIME→time.Timemapping ("true"/"false")Empty fields fall back to their defaults, so existing
Configliterals produce identical DSN
output to v0.9.0 — no migration required.Example
// Minimal — defaults produce charset=utf8mb4&loc=UTC&parseTime=true (same as v0.9.0) db := mysql.New(logger, mysql.Config{ Host: "localhost", Port: 3306, User: "app", Password: "secret", Name: "mydb", }) // Explicit — override when needed db := mysql.New(logger, mysql.Config{ Host: "localhost", Port: 3306, User: "app", Password: "secret", Name: "mydb", Charset: "utf8mb4", Loc: "America/Mexico_City", ParseTime: "false", // receive raw []byte for DATE columns })Known Limitations & Edge Cases
- No context on
Tx.Commit()/Tx.Rollback().database/sqldoes not support it. - No query builder. Repository code writes raw SQL strings.
- No migration helper. Schema migrations are out of scope.
- Collation cannot be set via DSN.
go-sql-driverv1.8.x negotiates the connection
collation using a 1-byte handshake ID (max 255). MariaDB 11.4+ collations such as
utf8mb4_uca1400_as_cscarry IDs > 255 and will cause a connection error if passed as a
DSNcollationparameter. Set the desired collation in your schema migrations at the
database/table level — column-level collation governsORDER BY,WHEREcomparisons,
andUNIQUEkey behaviour regardless of the connection collation.
Installation
go get code.nochebuena.dev/go/mysql@v0.9.1Requires Go 1.21 or later.
v0.9.x → v1.0.0 Roadmap
- Consider adding a
BeginTx(ctx, opts)variant for explicit transaction isolation levels. - Gather production feedback on connection pool defaults before hardening the config.
- Assess whether
*sql.DBstats (OpenConnections,WaitCount) should be surfaced for
observability.
v0.9.0
code.nochebuena.dev/go/mysqlOverview
mysqlis adatabase/sql-backed MySQL client that integrates with thelauncherlifecycle
andhealthcheck systems. It manages a*sql.DBconnection pool, maps MySQL driver errors to
portablexerrorscodes, and provides aUnitOfWorkimplementation that injects the active
transaction into the context so repositories participate in transactions without explicit wiring.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; pool opened inOnInit, not at constructionConfigstruct with env-tag support (MYSQL_HOST,MYSQL_PORT,MYSQL_USER,
MYSQL_PASSWORD,MYSQL_NAME,MYSQL_MAX_CONNS,MYSQL_MIN_CONNS, connection lifetime fields)UnitOfWorkinterface andNewUnitOfWork(logger, client)constructor using context injectionHandleError(err) errorpackage-level function mapping MySQL errors to xerrors:- Error 1062 (ER_DUP_ENTRY) →
ErrAlreadyExists - Errors 1216, 1217, 1451, 1452 (foreign key violations) →
ErrInvalidInput sql.ErrNoRows→ErrNotFound- all other errors →
ErrInternal
- Error 1062 (ER_DUP_ENTRY) →
- Driver imported as
mysqldrvalias inerrors.goto avoid name collision with this package health.Checkableimplementation athealth.LevelCritical
Installation
go get code.nochebuena.dev/go/mysql@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, andgithub.com/go-sql-driver/mysql.Design Highlights
database/sqlnative types throughout.Executorusessql.Result,*sql.Rows, and
*sql.Row. Method names followdatabase/sqlconvention (ExecContext,QueryContext,
QueryRowContext). This is intentionally distinct from thepostgresmodule, which uses pgx
types.Honest
Txcontract.database/sqldoes not support per-call context onCommitor
Rollback. TheTxinterface reflects this honestly —Commit()andRollback()take no
context — rather than accepting a context argument and silently ignoring it.Driver alias prevents name collision. The
go-sql-driver/mysqlpackage name would
collide with this package's namemysql. Inerrors.goit is imported asmysqldrv; in
mysql.goit is imported with_for side-effect driver registration only.UnitOfWork via context injection. Same pattern as the
postgresmodule: the active
*sql.Txis stored under an unexportedctxTxKey{}in the context.GetExecutor(ctx)returns
the transaction if present, otherwise*sql.DB.Error mapping by error number.
HandleErrortype-asserts to*mysqldrv.MySQLErrorand
switches on.Number— not message strings — to map driver errors to xerrors codes.Known Limitations & Edge Cases
- No context on
Tx.Commit()/Tx.Rollback().database/sqldoes not support it. A
commit or rollback cannot be cancelled by a deadline or context cancellation. - No query builder. Repository code writes raw SQL strings.
- No migration helper. Schema migrations are out of scope.
parseTime=trueandloc=UTCare hardcoded in the DSN. Applications that need a
different timezone or raw time bytes must construct their own DSN.
v0.9.0 → v1.0.0 Roadmap
- Evaluate whether DSN parameters (
parseTime,loc) should be exposed inConfig. - Consider adding a
BeginTx(ctx, opts)variant for explicit transaction isolation levels. - Gather production feedback on connection pool defaults before hardening the config.
- Assess whether
*sql.DBstats (OpenConnections, WaitCount) should be surfaced for observability.
Downloads
- No context on
-
Release 0.9.0 Stable
released this
2026-03-19 07:22:21 -06:00 | 1 commits to main since this releasev0.9.0
code.nochebuena.dev/go/mysqlOverview
mysqlis adatabase/sql-backed MySQL client that integrates with thelauncherlifecycle
andhealthcheck systems. It manages a*sql.DBconnection pool, maps MySQL driver errors to
portablexerrorscodes, and provides aUnitOfWorkimplementation that injects the active
transaction into the context so repositories participate in transactions without explicit wiring.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; pool opened inOnInit, not at constructionConfigstruct with env-tag support (MYSQL_HOST,MYSQL_PORT,MYSQL_USER,
MYSQL_PASSWORD,MYSQL_NAME,MYSQL_MAX_CONNS,MYSQL_MIN_CONNS, connection lifetime fields)UnitOfWorkinterface andNewUnitOfWork(logger, client)constructor using context injectionHandleError(err) errorpackage-level function mapping MySQL errors to xerrors:- Error 1062 (ER_DUP_ENTRY) →
ErrAlreadyExists - Errors 1216, 1217, 1451, 1452 (foreign key violations) →
ErrInvalidInput sql.ErrNoRows→ErrNotFound- all other errors →
ErrInternal
- Error 1062 (ER_DUP_ENTRY) →
- Driver imported as
mysqldrvalias inerrors.goto avoid name collision with this package health.Checkableimplementation athealth.LevelCritical
Installation
go get code.nochebuena.dev/go/mysql@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, andgithub.com/go-sql-driver/mysql.Design Highlights
database/sqlnative types throughout.Executorusessql.Result,*sql.Rows, and
*sql.Row. Method names followdatabase/sqlconvention (ExecContext,QueryContext,
QueryRowContext). This is intentionally distinct from thepostgresmodule, which uses pgx
types.Honest
Txcontract.database/sqldoes not support per-call context onCommitor
Rollback. TheTxinterface reflects this honestly —Commit()andRollback()take no
context — rather than accepting a context argument and silently ignoring it.Driver alias prevents name collision. The
go-sql-driver/mysqlpackage name would
collide with this package's namemysql. Inerrors.goit is imported asmysqldrv; in
mysql.goit is imported with_for side-effect driver registration only.UnitOfWork via context injection. Same pattern as the
postgresmodule: the active
*sql.Txis stored under an unexportedctxTxKey{}in the context.GetExecutor(ctx)returns
the transaction if present, otherwise*sql.DB.Error mapping by error number.
HandleErrortype-asserts to*mysqldrv.MySQLErrorand
switches on.Number— not message strings — to map driver errors to xerrors codes.Known Limitations & Edge Cases
- No context on
Tx.Commit()/Tx.Rollback().database/sqldoes not support it. A
commit or rollback cannot be cancelled by a deadline or context cancellation. - No query builder. Repository code writes raw SQL strings.
- No migration helper. Schema migrations are out of scope.
parseTime=trueandloc=UTCare hardcoded in the DSN. Applications that need a
different timezone or raw time bytes must construct their own DSN.
v0.9.0 → v1.0.0 Roadmap
- Evaluate whether DSN parameters (
parseTime,loc) should be exposed inConfig. - Consider adding a
BeginTx(ctx, opts)variant for explicit transaction isolation levels. - Gather production feedback on connection pool defaults before hardening the config.
- Assess whether
*sql.DBstats (OpenConnections, WaitCount) should be surfaced for observability.
Downloads