34 lines
3.0 KiB
Markdown
34 lines
3.0 KiB
Markdown
|
|
# 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: `Exec`, `Query`, `QueryRow` using native pgx types (`pgconn.CommandTag`, `pgx.Rows`, `pgx.Row`).
|
||
|
|
- `Tx` interface: embeds `Executor` and adds `Commit(ctx context.Context) error` and `Rollback(ctx context.Context) error`.
|
||
|
|
- `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` into a single injectable dependency.
|
||
|
|
- `UnitOfWork` interface: `Do(ctx context.Context, fn func(ctx context.Context) error) error`.
|
||
|
|
- `Config` struct: fields `Host`, `Port`, `User`, `Password`, `Name`, `SSLMode`, `Timezone`, `MaxConns`, `MinConns`, `MaxConnLifetime`, `MaxConnIdleTime`, `HealthCheckPeriod`; all settable via environment variables with `env` struct tags and sensible defaults.
|
||
|
|
- `Config.DSN() string`: constructs a `postgres://` URL including SSL mode and timezone query parameters.
|
||
|
|
- `New(logger logz.Logger, cfg Config) Component`: returns a `pgxpool`-backed component; pool is created lazily in `OnInit`.
|
||
|
|
- Lifecycle hooks: `OnInit` parses config and creates the connection pool with a 30-second timeout; `OnStart` pings the database with a 5-second timeout; `OnStop` closes the pool gracefully.
|
||
|
|
- `health.Checkable` implementation: `HealthCheck` delegates to `Ping`; `Name()` returns `"postgres"`; `Priority()` returns `health.LevelCritical`.
|
||
|
|
- `NewUnitOfWork(logger logz.Logger, client Client) UnitOfWork`: wraps a `Client` to provide transactional `Do` semantics; rolls back and logs on error, commits on success.
|
||
|
|
- `HandleError(err error) error` (package-level function): maps `*pgconn.PgError` codes to xerrors — `UniqueViolation` → `ErrAlreadyExists`, `ForeignKeyViolation` → `ErrInvalidInput`, `CheckViolation` → `ErrInvalidInput`; `pgx.ErrNoRows` → `ErrNotFound`; all other errors → `ErrInternal`.
|
||
|
|
- Transaction context injection: the active `pgx.Tx` is stored under an unexported `ctxTxKey{}` context key; `GetExecutor` returns the transaction when found, otherwise returns the pool.
|
||
|
|
- All pool reads guarded by `sync.RWMutex` for safe concurrent access.
|
||
|
|
|
||
|
|
### Design Notes
|
||
|
|
|
||
|
|
- All interfaces use pgx-native types (`pgconn.CommandTag`, `pgx.Rows`, `pgx.Row`) directly; there is no `database/sql` adapter. This is intentional and incompatible with the `mysql` module by design.
|
||
|
|
- `UnitOfWork.Do` injects the transaction into the context so repositories can call `GetExecutor(ctx)` transparently without knowing whether a transaction is active.
|
||
|
|
- PostgreSQL error codes are matched via `pgerrcode` constants and `errors.As`, never by parsing error message strings.
|
||
|
|
|
||
|
|
[0.9.0]: https://code.nochebuena.dev/go/postgres/releases/tag/v0.9.0
|