package postgres import ( "fmt" "net/url" ) // Config holds PostgreSQL connection settings. Required fields must be supplied // by the caller; optional fields have production-safe defaults via [DefaultConfig]. type Config struct { Host string `env:"EINHERJAR_PG_HOST,required"` Port int `env:"EINHERJAR_PG_PORT" envDefault:"5432"` User string `env:"EINHERJAR_PG_USER,required"` Password string `env:"EINHERJAR_PG_PASSWORD,required"` Name string `env:"EINHERJAR_PG_NAME,required"` SSLMode string `env:"EINHERJAR_PG_SSL_MODE" envDefault:"disable"` Timezone string `env:"EINHERJAR_PG_TIMEZONE" envDefault:"UTC"` MaxConns int `env:"EINHERJAR_PG_MAX_CONNS" envDefault:"5"` MinConns int `env:"EINHERJAR_PG_MIN_CONNS" envDefault:"2"` MaxConnLifetime string `env:"EINHERJAR_PG_MAX_CONN_LIFETIME" envDefault:"1h"` MaxConnIdleTime string `env:"EINHERJAR_PG_MAX_CONN_IDLE_TIME" envDefault:"30m"` HealthCheckPeriod string `env:"EINHERJAR_PG_HEALTH_CHECK_PERIOD" envDefault:"1m"` } // DefaultConfig returns a Config with all optional fields set to production-safe // defaults. Callers must supply Host, Port, User, Password, and Name. func DefaultConfig() Config { return Config{ Port: 5432, SSLMode: "disable", Timezone: "UTC", MaxConns: 5, MinConns: 2, MaxConnLifetime: "1h", MaxConnIdleTime: "30m", HealthCheckPeriod: "1m", } } // DSN constructs a PostgreSQL connection string from the configuration. func (c Config) DSN() string { u := &url.URL{ Scheme: "postgres", User: url.UserPassword(c.User, c.Password), Host: fmt.Sprintf("%s:%d", c.Host, c.Port), Path: "/" + c.Name, } q := u.Query() q.Set("sslmode", c.SSLMode) q.Set("timezone", c.Timezone) u.RawQuery = q.Encode() return u.String() }