Add BeginTx(ctx, *sql.TxOptions) to Client interface for explicit transaction isolation level control; Begin refactored as a convenience wrapper calling BeginTx(ctx, nil). Add Stats() sql.DBStats to Component interface for connection pool observability. Bump all micro-lib dependencies (logz, health, launcher, xerrors) from v0.9.0 to v1.0.0. API committed as stable.
5.6 KiB
5.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
Added
Client.BeginTx(ctx context.Context, opts *sql.TxOptions) (Tx, error)— starts a transaction with explicit isolation level and read-only options; accepts any*sql.TxOptionssupported bydatabase/sql.Component.Stats() sql.DBStats— returns connection pool metrics (OpenConnections,WaitCount,WaitDuration, etc.) for observability and alerting; returns zero value when called beforeOnInit.
Changed
Client.Begin(ctx context.Context) (Tx, error)— refactored as a convenience wrapper callingBeginTx(ctx, nil); behavior is identical, no breaking change.- All micro-lib dependencies bumped from v0.9.1 to v1.0.0:
logz,health,launcher,xerrors.
Unchanged
All other API (Executor, Tx, Client, Component, UnitOfWork, Config, New,
NewUnitOfWork, HandleError) is API-compatible with v0.9.1.
0.9.1 - 2026-03-20
Added
Config.Charset string(MYSQL_CHARSET, default"utf8mb4"): connection character set, sent asSET NAMES <charset>during handshake. Previously hardcoded toutf8mb4.Config.Loc string(MYSQL_LOC, default"UTC"): IANA timezone name used fortime.Time↔DATE/DATETIMEconversion. Previously hardcoded toUTC.Config.ParseTime string(MYSQL_PARSE_TIME, default"true"): controls driver-levelDATE/DATETIME→time.Timemapping. Valid values"true"/"false". Previously hardcoded totrue.
Changed
Config.DSN(): now derivescharset,loc, andparseTimefrom the new Config fields instead of hardcoded literals. Empty fields fall back to their respective defaults, preserving identical DSN output for callers that do not set the new fields.- Removed unused
net/url.URLconstruction fromDSN(); the method now builds params directly withurl.Values.
Notes
- Backward compatible. Existing
Configliterals that do not setCharset,Loc, orParseTimeproduce the same DSN as v0.9.0 (charset=utf8mb4&loc=UTC&parseTime=true). - Collation via DSN is not supported.
go-sql-driverv1.8.x negotiates the collation using a 1-byte handshake ID (max 255). MariaDB 11.4+ collations such asutf8mb4_uca1400_as_cscarry IDs > 255 and will cause a connection error if set in the DSN. Set the desired collation in schema migrations at the database/table level.
0.9.0 - 2026-03-18
Added
Executorinterface:ExecContext,QueryContext,QueryRowContextusingdatabase/sqltypes (sql.Result,*sql.Rows,*sql.Row).Txinterface: embedsExecutorand addsCommit() errorandRollback() error(no context argument, matchingdatabase/sqlsemantics).Clientinterface:GetExecutor(ctx context.Context) Executor,Begin(ctx context.Context) (Tx, error),Ping(ctx context.Context) error,HandleError(err error) error.Componentinterface: composeslauncher.Component,health.Checkable, andClient.UnitOfWorkinterface:Do(ctx context.Context, fn func(ctx context.Context) error) error.Configstruct: fieldsHost,Port,User,Password,Name,MaxConns,MinConns,MaxConnLifetime,MaxConnIdleTime; settable viaMYSQL_*environment variables with defaults (port3306, max conns5, idle conns2, lifetime1h, idle time30m).Config.DSN() string: constructs ago-sql-driverDSN inuser:pass@tcp(host:port)/db?parseTime=true&loc=UTCformat.New(logger logz.Logger, cfg Config) Component: returns a*sql.DB-backed component; the connection is opened lazily inOnInit.- Lifecycle hooks:
OnInitcallssql.Open, sets pool limits, and parses duration config fields;OnStartpings with a 5-second timeout;OnStopcloses the*sql.DB. health.Checkableimplementation:HealthCheckdelegates toPing;Name()returns"mysql";Priority()returnshealth.LevelCritical.NewUnitOfWork(logger logz.Logger, client Client) UnitOfWork: wraps aClientto provide transactionalDosemantics; rolls back and logs on error, commits on success.HandleError(err error) error(package-level function): maps*mysqldrv.MySQLErrorerror numbers to xerrors —1062(duplicate entry) →ErrAlreadyExists;1216,1217,1451,1452(foreign key violations) →ErrInvalidInput;sql.ErrNoRows→ErrNotFound; all other errors →ErrInternal.- Transaction context injection: the active
*sql.Txis stored under an unexportedctxTxKey{}context key;GetExecutorreturns it when found, otherwise returns*sql.DB. - All
*sql.DBreads guarded bysync.RWMutexfor safe concurrent access. go-sql-driver/mysqlis imported with a blank identifier inmysql.gofor driver side-effect registration, and asmysqldrvinerrors.goto avoid the package name collision.
Design Notes
Tx.Commit()andTx.Rollback()intentionally omit acontext.Contextargument, honestly reflecting thedatabase/sqllimitation rather than accepting and ignoring one.- The module is structurally parallel to
postgresbut usesdatabase/sqltypes throughout; the two modules are intentionally type-incompatible. - MySQL error codes are matched by numeric constant via
MySQLError.Number, not by string parsing, for stability across MySQL and MariaDB versions.