Files
golibs/datastores/sql/postgres/config.go
2026-02-13 00:09:11 -05:00

81 lines
2.0 KiB
Go

package postgres
import (
"context"
"fmt"
"os"
"github.com/jackc/pgx/v5"
)
// Config holds the database configuration.
type Config struct {
ctx context.Context
Host string
Port string
User string
Password string
DBName string
SSLMode string
}
// ConfigOption is a functional option for Config.
type ConfigOption func(*Config)
// WithContext sets the context on the config.
func WithContext(ctx context.Context) ConfigOption {
return func(c *Config) {
c.ctx = ctx
}
}
// NewConfig creates a new database configuration from environment variables.
// DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_SSL_MODE fall back to sensible
// defaults. DB_NAME is required and must be set in the environment.
func NewConfig(opts ...ConfigOption) *Config {
c := &Config{
Host: getEnvOrDefault("DB_HOST", "localhost"),
Port: getEnvOrDefault("DB_PORT", "5432"),
User: getEnvOrDefault("DB_USER", "postgres"),
Password: getEnvOrDefault("DB_PASSWORD", "postgres"),
DBName: os.Getenv("DB_NAME"),
SSLMode: getEnvOrDefault("DB_SSL_MODE", "disable"),
}
for _, opt := range opts {
opt(c)
}
return c
}
// DSN returns the database connection string in key=value format.
func (c *Config) DSN() string {
return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
c.Host, c.Port, c.User, c.Password, c.DBName, c.SSLMode)
}
// Connect creates a new single database connection using pgx.
func (c *Config) Connect() (*pgx.Conn, error) {
conn, err := pgx.Connect(c.Context(), c.DSN())
if err != nil {
return nil, fmt.Errorf("failed to connect to database: %w", err)
}
return conn, nil
}
// Context returns the context associated with this config, defaulting to
// context.Background() if none was set.
func (c *Config) Context() context.Context {
if c.ctx == nil {
c.ctx = context.Background()
}
return c.ctx
}
// getEnvOrDefault returns the value of an environment variable or a fallback.
func getEnvOrDefault(key, fallback string) string {
if value := os.Getenv(key); value != "" {
return value
}
return fallback
}