package pgdb import ( "fmt" "github.com/jackc/pgx/v5/pgxpool" "go.ntppool.org/common/database" ) // CreatePoolConfig converts database.PostgresConfig to pgxpool.Config // This is the secure way to create a config without exposing passwords in DSN strings func CreatePoolConfig(cfg *database.PostgresConfig) (*pgxpool.Config, error) { // Validate required fields if cfg.Host == "" { return nil, fmt.Errorf("postgres: host is required") } if cfg.User == "" { return nil, fmt.Errorf("postgres: user is required") } if cfg.Name == "" { return nil, fmt.Errorf("postgres: database name is required") } // Validate SSLMode validSSLModes := map[string]bool{ "disable": true, "allow": true, "prefer": true, "require": true, "verify-ca": true, "verify-full": true, } if cfg.SSLMode != "" && !validSSLModes[cfg.SSLMode] { return nil, fmt.Errorf("postgres: invalid sslmode: %s", cfg.SSLMode) } // Set defaults host := cfg.Host if host == "" { host = "localhost" } port := cfg.Port if port == 0 { port = 5432 } sslmode := cfg.SSLMode if sslmode == "" { sslmode = "prefer" } // Build connection string WITHOUT password // We'll set the password separately in the config connString := fmt.Sprintf("host=%s port=%d user=%s dbname=%s sslmode=%s", host, port, cfg.User, cfg.Name, sslmode) // Parse the connection string poolConfig, err := pgxpool.ParseConfig(connString) if err != nil { return nil, fmt.Errorf("postgres: failed to parse connection config: %w", err) } // Set password separately (security: never put password in the connection string) poolConfig.ConnConfig.Password = cfg.Pass return poolConfig, nil }