Documentation
¶
Overview ¶
Package postgres is Medusa's Postgres battery: a pgx connection pool with query logging, embedded goose migrations, and helpers that classify driver errors.
It is a separate module, so an app that does not use Postgres never downloads pgx or goose:
pool, err := postgres.Open(ctx, cfg.DatabaseURL, logger) ... err = postgres.Migrate(ctx, cfg.DatabaseURL, migrations.FS, logger)
Queries are the app's own (sqlc, or pgx directly). Conn is the interface they run on, so the same code works on the pool and inside a transaction.
Index ¶
- Constants
- func IsNoRows(err error) bool
- func IsUniqueViolation(err error) bool
- func Migrate(ctx context.Context, url string, migrations fs.FS, logger *slog.Logger) (err error)
- func Open(ctx context.Context, url string, logger *slog.Logger, opts ...Option) (*pgxpool.Pool, error)
- type Conn
- type Option
Constants ¶
const ( // DefaultMaxConns caps concurrent connections. Keep the total across all // replicas below the server's max_connections. DefaultMaxConns = 25 // DefaultConnMaxLifetime recycles connections so a load balancer or a // failover never leaves the pool holding a dead one indefinitely. DefaultConnMaxLifetime = time.Hour // DefaultConnMaxIdleTime closes connections nobody is using. DefaultConnMaxIdleTime = 10 * time.Minute // SlowQueryThreshold is when a statement is logged as slow. SlowQueryThreshold = 200 * time.Millisecond )
Connection pool defaults.
Variables ¶
This section is empty.
Functions ¶
func IsUniqueViolation ¶
IsUniqueViolation reports whether err is a broken unique constraint.
func Migrate ¶
Migrate applies every pending goose migration in migrations to the database at url and logs each one. The .sql files sit at the root of migrations, which is usually an embed.FS next to them:
//go:embed *.sql var FS embed.FS
Run it as its own deploy step, never on API startup. Two runs at once (two deploys, or a retried job) are serialized by a Postgres advisory lock, so the second waits and then finds nothing to apply. The lock lives in the session, so the URL must not go through a pooler in transaction mode.
func Open ¶
func Open(ctx context.Context, url string, logger *slog.Logger, opts ...Option) (*pgxpool.Pool, error)
Open opens a connection pool and pings it, so a bad URL or an unreachable host fails at startup rather than on the first request. Statements slower than SlowQueryThreshold are logged as warnings.
Types ¶
type Conn ¶
type Conn interface {
Exec(ctx context.Context, sql string, args ...any) (pgconn.CommandTag, error)
Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error)
QueryRow(ctx context.Context, sql string, args ...any) pgx.Row
Begin(ctx context.Context) (pgx.Tx, error)
}
Conn is what queries run on: a *pgxpool.Pool, or a pgx.Tx opened on it. It satisfies the DBTX interface sqlc generates, and Begin opens a transaction on the pool or a savepoint inside a transaction, so pgx.BeginFunc(ctx, conn, fn) nests correctly.