db

package
v0.3.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 17, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package db provides PostgreSQL database utilities optimized for SaaS applications.

This package wraps github.com/jackc/pgx/v5/pgxpool to provide connection pooling, health checks, and database migrations with sensible defaults for production workloads.

Features

  • Connection pooling with configurable limits and timeouts
  • Automatic retry logic with exponential backoff during startup
  • Health check function compatible with standard health check interfaces
  • Database migrations using github.com/pressly/goose/v3
  • Environment-based configuration for deployment convenience

Configuration

All settings are loaded from environment variables:

DATABASE_CONN_URL           - PostgreSQL connection URL (required)
DATABASE_MAX_OPEN_CONNS     - Maximum open connections (default: 10)
DATABASE_MIN_CONNS          - Minimum idle connections (default: 5)
DATABASE_HEALTHCHECK_PERIOD - Health check interval (default: 1m)
DATABASE_MAX_CONN_IDLE_TIME - Maximum connection idle time (default: 10m)
DATABASE_MAX_CONN_LIFETIME  - Maximum connection lifetime (default: 30m)
DATABASE_RETRY_ATTEMPTS     - Connection retry attempts (default: 3)
DATABASE_RETRY_INTERVAL     - Base retry interval (default: 5s)
DATABASE_MIGRATIONS_TABLE   - Migrations table name (default: schema_migrations)

Usage

Basic connection setup with Config:

import (
	"context"
	"log"
	"os"

	"github.com/dmitrymomot/forge/pkg/db"
)

func main() {
	ctx := context.Background()

	pool, err := db.Open(ctx, db.Config{
		URL:      os.Getenv("DATABASE_CONN_URL"),
		MaxConns: 10,
		MinConns: 5,
	})
	if err != nil {
		log.Fatal(err)
	}
	defer pool.Close()
}

Health Checks

The Healthcheck function returns a closure suitable for health check endpoints:

import (
	"context"
	"net/http"

	"github.com/dmitrymomot/forge/pkg/db"
)

func healthHandler(pool *db.Pool) http.HandlerFunc {
	healthFn := db.Healthcheck(pool)
	return func(w http.ResponseWriter, r *http.Request) {
		if err := healthFn(r.Context()); err != nil {
			w.WriteHeader(http.StatusServiceUnavailable)
			return
		}
		w.WriteHeader(http.StatusOK)
	}
}

Transactions

The WithTx helper provides automatic transaction management with rollback on error:

import (
	"context"

	"github.com/dmitrymomot/forge/pkg/db"
)

err := db.WithTx(ctx, pool, func(tx pgx.Tx) error {
	// Execute queries using tx
	return tx.QueryRow(ctx, "SELECT 1").Scan(&result)
})
if err != nil {
	// Transaction was rolled back automatically
}

Migrations

Run database migrations using embedded SQL files:

import (
	"context"
	"embed"
	"log/slog"

	"github.com/dmitrymomot/forge/pkg/db"
)

//go:embed *.sql
var migrations embed.FS

err := db.Migrate(ctx, pool, migrations, logger)
if err != nil {
	log.Fatal(err)
}

Error Handling

The package defines sentinel errors for common failure modes:

Errors are wrapped using errors.Join to preserve the original error context.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrFailedToParseDBConfig    = errors.New("db: failed to parse database configuration")
	ErrFailedToOpenDBConnection = errors.New("db: failed to open database connection")
	ErrHealthcheckFailed        = errors.New("db: healthcheck failed")
	ErrSetDialect               = errors.New("db migrator: failed to set dialect")
	ErrApplyMigrations          = errors.New("db migrator: failed to apply migrations")
)

Functions

func Healthcheck

func Healthcheck(conn *pgxpool.Pool) func(context.Context) error

Healthcheck returns a closure that validates database connectivity for health endpoints. Uses closure pattern to inject the connection dependency while maintaining compatibility with standard health check interfaces that expect func(context.Context) error.

func Migrate

func Migrate(ctx context.Context, pool *pgxpool.Pool, migrations embed.FS, log *slog.Logger) error

Migrate runs database migrations using the embedded SQL files. Uses hardcoded defaults: FS root (".") directory and "schema_migrations" table. Pass nil for log to disable migration logging.

func MustOpen

func MustOpen(ctx context.Context, cfg Config, opts ...Option) *pgxpool.Pool

MustOpen creates a connection pool or exits on failure. Use for simple applications where startup failure is fatal.

Example:

pool := db.MustOpen(ctx, db.Config{URL: os.Getenv("DATABASE_URL")},
    db.WithMigrations(migrations),
    db.WithLogger(log),
)

func Open

func Open(ctx context.Context, cfg Config, opts ...Option) (*pgxpool.Pool, error)

Open creates a PostgreSQL connection pool with sensible defaults. Supports optional migrations and configurable pool settings via Config.

Example:

//go:embed *.sql
var migrations embed.FS

pool, err := db.Open(ctx, db.Config{URL: "postgres://user:pass@host:5432/db"},
    db.WithMigrations(migrations),
    db.WithLogger(log),
)

func Shutdown

func Shutdown(pool *pgxpool.Pool) func(ctx context.Context) error

Shutdown returns a function that gracefully closes the database connection pool. Use with forge.WithShutdownHook().

Example:

app := forge.New(
    forge.WithShutdownHook(db.Shutdown(pool)),
)

func WithTx

func WithTx(ctx context.Context, pool *pgxpool.Pool, fn func(tx pgx.Tx) error) error

WithTx executes fn within a database transaction. If fn returns an error, the transaction is rolled back. If fn panics, the transaction is rolled back and the panic is re-raised. If fn succeeds, the transaction is committed.

Types

type Config

type Config struct {
	URL               string        `env:"URL,required"`
	MaxConns          int32         `env:"MAX_CONNS"           envDefault:"10"`
	MinConns          int32         `env:"MIN_CONNS"           envDefault:"5"`
	HealthCheckPeriod time.Duration `env:"HEALTH_CHECK_PERIOD" envDefault:"1m"`
	MaxConnIdleTime   time.Duration `env:"MAX_CONN_IDLE_TIME"  envDefault:"10m"`
	MaxConnLifetime   time.Duration `env:"MAX_CONN_LIFETIME"   envDefault:"30m"`
	RetryAttempts     int           `env:"RETRY_ATTEMPTS"      envDefault:"3"`
	RetryInterval     time.Duration `env:"RETRY_INTERVAL"      envDefault:"5s"`
}

Config holds database connection configuration.

type Option

type Option func(*options)

Option configures database connection.

func WithLogger

func WithLogger(log *slog.Logger) Option

WithLogger sets the logger for migrations and connection events.

func WithMigrations

func WithMigrations(fs embed.FS) Option

WithMigrations enables automatic migrations using embedded SQL files.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL