Files
postgres/CHANGELOG.md
Rene Nochebuena 4d6d2f1d62 feat(postgres)!: promote to v1.0.0 — BeginTx with pgx options, Stats, bump all deps to v1.0.0
Add BeginTx(ctx, pgx.TxOptions) to Client interface for explicit isolation level and
read-only transaction control; Begin refactored as a convenience wrapper calling
BeginTx(ctx, pgx.TxOptions{}). Add Stats() *pgxpool.Stat 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.
2026-05-11 19:36:47 -06:00

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

1.0.0 — 2026-05-12

Added

  • Client.BeginTx(ctx context.Context, opts pgx.TxOptions) (Tx, error) — starts a transaction with explicit isolation level and read-only options using pgx-native pgx.TxOptions.
  • Component.Stats() *pgxpool.Stat — returns connection pool metrics (TotalConns, IdleConns, AcquiredConns, MaxConns, etc.) for observability and alerting; returns a zero-value *pgxpool.Stat when called before OnInit.

Changed

  • Client.Begin(ctx context.Context) (Tx, error) — refactored as a convenience wrapper calling BeginTx(ctx, pgx.TxOptions{}); behavior is identical, no breaking change.
  • All micro-lib dependencies bumped from v0.9.0 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.0.

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.