Documentation
¶
Overview ¶
Package database provides PostgreSQL connection pooling with transaction management and health checks. It wraps pgxpool for connection pooling with configurable limits, timeouts, and automatic reconnection.
Example usage:
cfg := config.DatabaseConfig{
Host: "localhost",
Port: 5432,
Database: "mydb",
User: "user",
Password: "pass",
MaxConns: 10,
}
pool, err := database.NewPool(ctx, cfg)
if err != nil {
log.Fatal(err)
}
defer pool.Close()
// Execute a query
rows, err := pool.Query(ctx, "SELECT id, name FROM users WHERE active = $1", true)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
// Use transactions
err = pool.WithTransaction(ctx, func(tx Transaction) error {
_, err := tx.Exec(ctx, "INSERT INTO users (name) VALUES ($1)", "John")
return err
})
Index ¶
- func CheckHealth(ctx context.Context, db *Pool) error
- func MustCommit(ctx context.Context, tx Transaction)
- func MustRollback(ctx context.Context, tx Transaction)
- func WithTransaction(ctx context.Context, pool *Pool, fn TransactionFunc) error
- type Database
- type Pool
- func (p *Pool) Begin(ctx context.Context) (Transaction, error)
- func (p *Pool) Check(ctx context.Context) error
- func (p *Pool) Close()
- func (p *Pool) Exec(ctx context.Context, sql string, args ...interface{}) (pgconn.CommandTag, error)
- func (p *Pool) HealthCheck(ctx context.Context) error
- func (p *Pool) Ping(ctx context.Context) error
- func (p *Pool) PingWithTimeout(ctx context.Context, timeout time.Duration) error
- func (p *Pool) Query(ctx context.Context, sql string, args ...interface{}) (pgx.Rows, error)
- func (p *Pool) QueryRow(ctx context.Context, sql string, args ...interface{}) pgx.Row
- func (p *Pool) Stats() *pgxpool.Stat
- func (p *Pool) WithTransaction(ctx context.Context, fn TransactionFunc) error
- type PoolInterface
- type Transaction
- type TransactionFunc
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CheckHealth ¶
CheckHealth performs a health check on the database by executing a simple query. It returns nil if the database is healthy, or an error if the database is unreachable or the query times out.
The default timeout is 5 seconds unless the context has a shorter timeout.
func MustCommit ¶
func MustCommit(ctx context.Context, tx Transaction)
MustCommit commits the transaction and panics if an error occurs. This is useful for scenarios where a commit failure is unrecoverable.
Use with caution - prefer proper error handling in production code.
func MustRollback ¶
func MustRollback(ctx context.Context, tx Transaction)
MustRollback rolls back the transaction and panics if an error occurs. This is useful for cleanup in defer statements where error handling is difficult.
Use with caution - prefer proper error handling in production code.
func WithTransaction ¶
func WithTransaction(ctx context.Context, pool *Pool, fn TransactionFunc) error
WithTransaction is a convenience function that executes a function within a transaction. It's equivalent to calling pool.WithTransaction(ctx, fn).
The transaction is automatically rolled back if the function returns an error or panics. The transaction is committed if the function returns nil.
Example usage:
err := database.WithTransaction(ctx, pool, func(tx database.Transaction) error {
_, err := tx.Exec(ctx, "INSERT INTO users (name) VALUES ($1)", "Alice")
if err != nil {
return err
}
_, err = tx.Exec(ctx, "INSERT INTO orders (user_id, total) VALUES ($1, $2)", 1, 100.0)
return err
})
Types ¶
type Database ¶
type Database interface {
// Query executes a query that returns rows, typically a SELECT.
// The args are for any placeholder parameters in the query.
Query(ctx context.Context, sql string, args ...interface{}) (pgx.Rows, error)
// QueryRow executes a query that is expected to return at most one row.
// QueryRow always returns a non-nil value. Errors are deferred until Row's Scan method is called.
// If the query selects no rows, the *Row's Scan will return ErrNoRows.
// Otherwise, the *Row's Scan scans the first selected row and discards the rest.
QueryRow(ctx context.Context, sql string, args ...interface{}) pgx.Row
// Exec executes a query that doesn't return rows, typically INSERT, UPDATE, or DELETE.
// The args are for any placeholder parameters in the query.
Exec(ctx context.Context, sql string, args ...interface{}) (pgconn.CommandTag, error)
}
Database defines the common interface for database operations. Both Pool and Transaction implement this interface, allowing for consistent API whether working with the connection pool or within a transaction.
type Pool ¶
type Pool struct {
// contains filtered or unexported fields
}
Pool wraps pgxpool.Pool and implements the Database interface. It manages a pool of connections to PostgreSQL with automatic reconnection and configurable connection limits.
func NewPool ¶
NewPool creates a new connection pool from the provided configuration. It establishes connections to PostgreSQL with the configured limits, timeouts, and SSL settings.
The context is used for the initial connection attempt. If the context is canceled or times out before the connection is established, an error is returned.
func (*Pool) Begin ¶
func (p *Pool) Begin(ctx context.Context) (Transaction, error)
Begin starts a new transaction. The returned Transaction must be committed or rolled back.
func (*Pool) Check ¶
Check implements the health.Checker interface for the database pool. This allows the pool to be used directly with the health check framework.
Example usage:
import "github.com/Combine-Capital/cqi/pkg/health"
h := health.New()
h.RegisterChecker("database", dbPool)
func (*Pool) Close ¶
func (p *Pool) Close()
Close closes all connections in the pool. After calling Close, the pool should not be used.
func (*Pool) Exec ¶
func (p *Pool) Exec(ctx context.Context, sql string, args ...interface{}) (pgconn.CommandTag, error)
Exec executes a query that doesn't return rows, typically INSERT, UPDATE, or DELETE.
func (*Pool) HealthCheck ¶
HealthCheck performs a comprehensive health check including connection pool stats. It returns an error if the database is unhealthy, along with diagnostic information.
func (*Pool) PingWithTimeout ¶
Ping verifies a connection to the database is still alive. This is a convenience wrapper around Pool.Ping that implements HealthChecker interface.
func (*Pool) WithTransaction ¶
func (p *Pool) WithTransaction(ctx context.Context, fn TransactionFunc) error
WithTransaction executes the provided function within a transaction. If the function returns an error, the transaction is rolled back. Otherwise, the transaction is committed. This ensures proper cleanup even if the function panics.
type PoolInterface ¶
type PoolInterface interface {
Query(ctx context.Context, sql string, args ...interface{}) (pgx.Rows, error)
QueryRow(ctx context.Context, sql string, args ...interface{}) pgx.Row
Exec(ctx context.Context, sql string, args ...interface{}) (pgconn.CommandTag, error)
Begin(ctx context.Context) (pgx.Tx, error)
Ping(ctx context.Context) error
Close()
Stat() *pgxpool.Stat
}
PoolInterface defines the interface for a connection pool. This allows for easier testing with mock implementations.
type Transaction ¶
type Transaction interface {
Database
// Commit commits the transaction.
Commit(ctx context.Context) error
// Rollback aborts the transaction.
Rollback(ctx context.Context) error
}
Transaction extends Database with transaction control methods. It allows committing or rolling back the transaction.
func BeginTransaction ¶
func BeginTransaction(ctx context.Context, pool *Pool) (Transaction, error)
BeginTransaction is a convenience function that starts a new transaction from a Pool. It's equivalent to calling pool.Begin(ctx).
Example usage:
tx, err := database.BeginTransaction(ctx, pool)
if err != nil {
return err
}
defer tx.Rollback(ctx) // Rollback if not committed
// Perform operations
_, err = tx.Exec(ctx, "INSERT INTO users (name) VALUES ($1)", "Alice")
if err != nil {
return err
}
// Commit transaction
return tx.Commit(ctx)
type TransactionFunc ¶
type TransactionFunc func(tx Transaction) error
TransactionFunc is a function that performs database operations within a transaction. If it returns an error, the transaction will be rolled back. If it returns nil, the transaction will be committed.