Files
postgres/CHANGELOG.md
Rene Nochebuena 2baafa6a0c feat(postgres): initial stable release v0.9.0
pgx v5-native PostgreSQL client with launcher lifecycle, health check, unit-of-work via context injection, and structured error mapping.

What's included:
- Executor / Tx / Client / Component interfaces using pgx native types (pgconn.CommandTag, pgx.Rows, pgx.Row)
- New(logger, cfg) constructor; pgxpool initialised in OnInit
- Config struct with env-tag support for all pool tuning parameters
- UnitOfWork via context injection; GetExecutor(ctx) returns active Tx or pool
- HandleError mapping pgerrcode constants to xerrors codes (AlreadyExists, InvalidInput, NotFound, Internal)
- health.Checkable at LevelCritical; HealthCheck delegates to pgxpool.Ping

Tested-via: todo-api POC integration
Reviewed-against: docs/adr/
2026-03-19 13:18:07 +00:00

3.0 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.

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 — UniqueViolationErrAlreadyExists, ForeignKeyViolationErrInvalidInput, CheckViolationErrInvalidInput; pgx.ErrNoRowsErrNotFound; 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.