package driver import ( "fmt" "net/url" "strconv" "git.unkin.net/unkin/waitfordb/internal/config" _ "github.com/jackc/pgx/v5/stdlib" // registers the "pgx" database/sql driver ) func init() { register(postgres{}) } type postgres struct{} func (postgres) Name() string { return "postgres" } func (postgres) Open(cfg config.Config) (Pinger, error) { dsn := cfg.DSN if dsn == "" { dsn = postgresDSN(cfg) } return openSQL("pgx", dsn) } // postgresDSN builds a URL-style DSN. net/url escapes the userinfo and query so // passwords with special characters are handled safely. func postgresDSN(cfg config.Config) string { u := url.URL{ Scheme: "postgres", Host: fmt.Sprintf("%s:%s", cfg.Host, cfg.Port), Path: "/" + cfg.Database, } if cfg.User != "" { u.User = url.UserPassword(cfg.User, cfg.Password) } q := url.Values{} if cfg.SSLMode != "" { q.Set("sslmode", cfg.SSLMode) } // connect_timeout is a per-attempt safety net in addition to the context // deadline the wait loop applies; it is in whole seconds. if secs := int(cfg.ConnectTimeout.Seconds()); secs > 0 { q.Set("connect_timeout", strconv.Itoa(secs)) } u.RawQuery = q.Encode() return u.String() }