Add PostgreSQL support to database package alongside existing MySQL support. Both databases share common infrastructure (pool management, metrics, transactions) while using database-specific connectors. database/ changes: - Add PostgresConfig struct and PostgreSQL connector using pgx/stdlib - Change MySQL config from DBConfig to *MySQLConfig (pointer) - Add Config.Validate() to prevent multiple database configs - Add PostgreSQL connector with secure config building (no password in DSN) - Add field validation and secure defaults (SSLMode="prefer") - Support legacy flat PostgreSQL config format for backward compatibility - Add tests for PostgreSQL configs and validation New database/pgdb/ package: - Native pgx connection pool support (*pgxpool.Pool) - OpenPool() and OpenPoolWithConfigFile() APIs - CreatePoolConfig() for secure config conversion - PoolOptions for fine-grained pool control - Full test coverage and documentation Security: - Passwords never exposed in DSN strings - Set passwords separately in pgx config objects - Validate all configuration before connection Architecture: - Shared code in database/ for both MySQL and PostgreSQL (sql.DB) - database/pgdb/ for PostgreSQL-specific native pool support
2.8 KiB
2.8 KiB
pgdb - Native PostgreSQL Connection Pool
Primary package for PostgreSQL connections using native pgx pool (*pgxpool.Pool
). Provides better performance and PostgreSQL-specific features compared to database/sql
.
Usage
Basic Example
import (
"context"
"go.ntppool.org/common/database/pgdb"
)
func main() {
ctx := context.Background()
// Open pool with default options
pool, err := pgdb.OpenPool(ctx, pgdb.DefaultPoolOptions())
if err != nil {
log.Fatal(err)
}
defer pool.Close()
// Use the pool for queries
row := pool.QueryRow(ctx, "SELECT version()")
var version string
row.Scan(&version)
}
With Custom Config File
pool, err := pgdb.OpenPoolWithConfigFile(ctx, "/path/to/database.yaml")
With Custom Pool Settings
opts := pgdb.DefaultPoolOptions()
opts.MaxConns = 50
opts.MinConns = 5
opts.MaxConnLifetime = 2 * time.Hour
pool, err := pgdb.OpenPool(ctx, opts)
Configuration Format
Recommended: Nested Format (database.yaml)
postgres:
host: localhost
port: 5432
user: myuser
pass: mypassword
name: mydb
sslmode: prefer
Legacy: Flat Format (backward compatible)
host: localhost
port: 5432
user: myuser
pass: mypassword
name: mydb
sslmode: prefer
Configuration Options
PoolOptions
ConfigFiles
- List of config file paths to search (default:database.yaml
,/vault/secrets/database.yaml
)MinConns
- Minimum connections (default: 0)MaxConns
- Maximum connections (default: 25)MaxConnLifetime
- Connection lifetime (default: 1 hour)MaxConnIdleTime
- Idle timeout (default: 30 minutes)HealthCheckPeriod
- Health check interval (default: 1 minute)
PostgreSQL Config Fields
host
- Database host (required)user
- Database user (required)pass
- Database passwordname
- Database name (required)port
- Port number (default: 5432)sslmode
- SSL mode:disable
,allow
,prefer
,require
,verify-ca
,verify-full
(default:prefer
)
Environment Variables
DATABASE_CONFIG_FILE
- Override config file location
When to Use
Use pgdb.OpenPool()
(this package) when:
- You need native PostgreSQL features (LISTEN/NOTIFY, COPY, etc.)
- You want better performance
- You're writing new PostgreSQL code
Use database.OpenDB()
(sql.DB) when:
- You need database-agnostic code
- You're using SQLC or other tools that expect
database/sql
- You need to support both MySQL and PostgreSQL
Security
This package avoids password exposure by:
- Never constructing DSN strings with passwords
- Setting passwords separately in pgx config objects
- Validating all configuration before connection
See Also
database/
- Generic sql.DB support for MySQL and PostgreSQL- pgx documentation: https://github.com/jackc/pgx