db

package
v0.0.0-...-6dc5f64 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 16, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package db is the core's access to PostgreSQL (ADR-0003): a pool of the runtime role's connections, transactions with commit hooks, the check of the schema version, and the migrations, which only whitetower migrate applies, as the migration role (threat model, DC-3).

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrSchemaBehind means that the database lacks migrations the binary
	// needs.
	ErrSchemaBehind = errors.New("the database schema is older than this binary: run whitetower migrate")
	// ErrSchemaAhead means that the database has migrations the binary does
	// not know.
	ErrSchemaAhead = errors.New("the database schema is newer than this binary")
)
View Source
var ExpectedVersion = sync.OnceValue(func() int64 {
	entries, err := fs.ReadDir(migrations(), ".")
	if err != nil {
		panic(err)
	}
	var latest int64
	for _, e := range entries {
		v, err := goose.NumericComponent(e.Name())
		if err != nil {
			panic(fmt.Sprintf("migration %s: %v", e.Name(), err))
		}
		latest = max(latest, v)
	}
	return latest
})

ExpectedVersion returns the version of the newest migration in the binary: the schema it needs.

Functions

func Migrate

func Migrate(ctx context.Context, cfg config.Migration, logger *slog.Logger) error

Migrate applies the pending migrations as the migration role. Concurrent runs, such as the init containers of several replicas, take turns on an advisory lock: one migrates while the others wait, up to 30 minutes, then find nothing left to do. It also lets the runtime role read the version table, through which the server checks the schema.

Types

type DB

type DB struct {
	// contains filtered or unexported fields
}

DB is a pool of the runtime role's connections. Its Exec, Query and QueryRow run outside any transaction; with them, DB serves the code that sqlc generates, as Tx does.

func Open

func Open(cfg config.Database) (*DB, error)

Open prepares a pool of the runtime role's connections. It connects only when a connection is needed: a database that is down fails the readiness check, not the startup.

func (*DB) CheckSchema

func (db *DB) CheckSchema(ctx context.Context) error

CheckSchema returns nil when the database's schema is the one the binary needs, and otherwise an error that wraps ErrSchemaBehind or ErrSchemaAhead. It is the readiness check "schema": the server waits for whitetower migrate, and refuses to start on a newer schema.

func (*DB) Close

func (db *DB) Close()

Close closes every connection of the pool.

func (*DB) Connect

func (db *DB) Connect(ctx context.Context, purpose string, idle time.Duration) (*pgx.Conn, error)

Connect opens a session of the runtime role outside the pool, for work that holds a session: the notification listener and the locks of the background jobs. pg_stat_activity names it after the pool's connections and its purpose. The database ends the session once it has run no statement for idle, so that a replica cut off from the database neither holds locks nor holds back notifications for longer: the caller checks in more often. Closing the connection ends the session, and with it its locks and listens.

func (*DB) Exec

func (db *DB) Exec(ctx context.Context, sql string, args ...any) (pgconn.CommandTag, error)

Exec runs a statement outside any transaction.

func (*DB) InTx

func (db *DB) InTx(ctx context.Context, fn func(ctx context.Context, tx *Tx) error) error

InTx runs fn in a transaction of the runtime role, then the BeforeCommit hooks; then it commits and runs the AfterCommit hooks. An error from fn or from a BeforeCommit hook, or a panic, rolls everything back, and no AfterCommit hook runs. A transaction that loses a serialization conflict or a deadlock runs again, up to three times in all: fn must have no effect outside the transaction except through its hooks.

func (*DB) Ping

func (db *DB) Ping(ctx context.Context) error

Ping checks that the database answers. It is the readiness check "database".

func (*DB) Query

func (db *DB) Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error)

Query runs a query outside any transaction.

func (*DB) QueryRow

func (db *DB) QueryRow(ctx context.Context, sql string, args ...any) pgx.Row

QueryRow runs a query that returns at most one row, outside any transaction.

func (*DB) Version

func (db *DB) Version(ctx context.Context) (int64, error)

Version returns the version of the last migration applied to the database, or 0 if none has run yet.

type Tx

type Tx struct {
	// contains filtered or unexported fields
}

Tx is a transaction that InTx runs. It runs statements but cannot end the transaction: InTx commits it or rolls it back.

func (*Tx) AfterCommit

func (t *Tx) AfterCommit(fn func(ctx context.Context))

AfterCommit registers fn to run once the transaction has committed, for what must never happen for a change that rolled back and cannot take part in the transaction, such as work outside the database. fn gets a context that the caller's cancellation does not end, and handles its own failures: the change is already made. Notifications to the other replicas need no hook: notify.Bus sends them in the transaction itself.

func (*Tx) BeforeCommit

func (t *Tx) BeforeCommit(fn func(ctx context.Context) error)

BeforeCommit registers fn to run in the transaction, after the work and just before the commit; an error rolls the whole transaction back. It serves what must be done, or checked, once the transaction's work is complete.

func (*Tx) CopyFrom

func (t *Tx) CopyFrom(ctx context.Context, table pgx.Identifier, columns []string, rows pgx.CopyFromSource) (int64, error)

CopyFrom inserts rows in bulk, in the transaction.

func (*Tx) Exec

func (t *Tx) Exec(ctx context.Context, sql string, args ...any) (pgconn.CommandTag, error)

Exec runs a statement in the transaction.

func (*Tx) Query

func (t *Tx) Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error)

Query runs a query in the transaction.

func (*Tx) QueryRow

func (t *Tx) QueryRow(ctx context.Context, sql string, args ...any) pgx.Row

QueryRow runs a query that returns at most one row, in the transaction.

func (*Tx) SendBatch

func (t *Tx) SendBatch(ctx context.Context, b *pgx.Batch) pgx.BatchResults

SendBatch sends a batch of statements, in the transaction.

Directories

Path Synopsis
Package dbtest gives integration tests a PostgreSQL database set up as in a deployment: a migration role that owns the schema, and a runtime role, member of whitetower_runtime, for the server.
Package dbtest gives integration tests a PostgreSQL database set up as in a deployment: a migration role that owns the schema, and a runtime role, member of whitetower_runtime, for the server.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL