81 lines
2.0 KiB
Go
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
|
|
}
|