Documentation
¶
Overview ¶
Package postgres provides PostgreSQL connection, migration, and metrics infrastructure.
Index ¶
Constants ¶
const (
// DefaultPingTimeoutSeconds is the default timeout for database ping operations
DefaultPingTimeoutSeconds = 15
)
Variables ¶
var Migrations embed.FS
Migrations holds the embedded, forward-only SQL migrations applied by Client.Migrate at startup. It is the same directory sqlc reads its schema from (see sqlc.yaml), so the generated types and the live schema share a single source of truth.
Functions ¶
func ClosePool ¶
ClosePool closes the pool, bounding the wait by timeout. pgxpool.Pool.Close blocks until every connection is returned to the pool and closed, so a connection wedged mid-query (or on a dead socket) can otherwise hang shutdown indefinitely. On timeout ClosePool stops waiting and returns an error; the abandoned Close finishes on its own if it can make progress, and the process is exiting regardless. It returns nil once Close completes within the timeout. A non-positive timeout waits indefinitely (the raw Close behaviour).
func NewPool ¶
NewPool parses the connection URI and returns a pgx pool configured with the supplied tuning knobs. Building the pool through ParseConfig + NewWithConfig (rather than pgxpool.New) is what lets callers size the pool explicitly instead of inheriting the all-default settings, which are frequently wrong under load. The pool connects lazily; callers should Ping before serving to surface an unreachable database at startup.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client provides the PostgreSQL lifecycle operations used by the application. Domain queries live in repositories rather than on this type.
func Open ¶
Open creates and initializes a new PostgreSQL database client. It accepts a context for timeout control and various configuration options. The client must be configured with a database connection using WithURI, WithPool, etc.
func (*Client) Migrate ¶
Migrate applies all pending, forward-only migrations from the embedded filesystem. goose tracks applied migrations by numeric version in its own table and runs each inside its own transaction. It is safe to call on every invocation: already-applied versions are skipped and a fully-migrated database is a no-op. A PostgreSQL session advisory lock serializes concurrent callers.
goose keys purely on the version number and does not checksum migration bodies, so editing an already-applied file is silently ignored — change the schema by adding a new versioned migration, never by editing an applied one.
func (*Client) MigrationStatus ¶
func (client *Client) MigrationStatus(ctx context.Context, migrationFS embed.FS) (database.MigrationStatus, error)
MigrationStatus reports whether all, some, or none of the embedded migrations have been applied. It derives the coarse database.MigrationStatus from goose's per-migration status list.
It is not strictly read-only: querying status ensures goose's version table exists, so calling it against a pristine database creates that table (with no migration rows). Keep this in mind before wiring it into a readiness probe.
type Option ¶
Option configures a Client instance during initialization. Options are passed to the Open function to customize the client's behavior.
func WithConnection ¶
WithConnection configures the client to use an existing PostgreSQL connection. Useful for sharing connections or when you need custom connection configuration.
func WithLogger ¶
WithLogger configures the client to use a specific logger instance. If not provided, operations will use a no-op logger.
func WithPingTimeout ¶
WithPingTimeout sets the timeout duration in seconds for database ping operations. Default timeout is DefaultPingTimeoutSeconds. Set to 0 to disable timeout.
func WithPool ¶
WithPool configures the client to use an existing PostgreSQL connection pool. This is the recommended option for production use as it provides connection pooling.
type PoolCollector ¶
type PoolCollector struct {
// contains filtered or unexported fields
}
PoolCollector is a prometheus.Collector that exposes pgxpool connection-pool statistics. It reads pool.Stat() lazily on every scrape rather than sampling on a timer, so each /metrics scrape reflects the pool's live state with no background goroutine to manage or leak.
Surfacing acquired/idle/total counts alongside the empty-acquire and canceled-acquire counters makes connection-pool saturation visible before it manifests as query timeouts: a rising empty-acquire count with acquired pinned at max is exhaustion.
func NewPoolCollector ¶
func NewPoolCollector(pool *pgxpool.Pool) *PoolCollector
NewPoolCollector builds a collector reading from the supplied pool. Register it on a Prometheus registry (typically prometheus.MustRegister so it is exposed by the same /metrics handler as the rest of the server's metrics).
func (*PoolCollector) Collect ¶
func (c *PoolCollector) Collect(ch chan<- prometheus.Metric)
Collect implements prometheus.Collector. It takes a single stats snapshot per scrape so every metric in the scrape is internally consistent.
func (*PoolCollector) Describe ¶
func (c *PoolCollector) Describe(ch chan<- *prometheus.Desc)
Describe implements prometheus.Collector.
type PoolConfig ¶
type PoolConfig struct {
// MaxConns caps the pool size. 0 keeps the pgx default (the greater of 4
// and runtime.NumCPU()).
MaxConns int
// MinConns is the number of idle connections the pool keeps warm. 0 keeps
// the pgx default (0).
MinConns int
// MaxConnLifetimeSeconds closes and replaces a connection this long after
// it was created. 0 keeps the pgx default (1 hour).
MaxConnLifetimeSeconds int
// MaxConnIdleTimeSeconds closes a connection that has been idle this long.
// 0 keeps the pgx default (30 minutes).
MaxConnIdleTimeSeconds int
// HealthCheckPeriodSeconds is the interval between pool health checks of
// idle connections. 0 keeps the pgx default (1 minute).
HealthCheckPeriodSeconds int
}
PoolConfig carries the connection-pool tuning knobs applied on top of the settings parsed from the connection URI. Every field is optional: a zero value leaves the corresponding pgx default in place, so callers only set the knobs they care about. Counts are plain integers; durations are expressed in seconds to match the surrounding config surface.