Help us shape the future of Go! Take the 2026 Go Developer Survey

database

package
v1.0.0-rc.10 Latest Latest
Warning

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

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

Documentation

Overview

Package database owns PostgreSQL handles and checked query/transaction mechanics.

Index

Constants

This section is empty.

Variables

View Source
var ErrHeldElsewhere = errors.New("held by another session")

ErrHeldElsewhere: another session holds the exclusive lock asked for.

View Source
var ErrInjectedFailure = fmt.Errorf("injected statement failure")

Functions

func Lookup

func Lookup(err error) (bool, error)

Lookup sorts a single-row read's outcome: found, absent, or failed.

found, err := Lookup(a.DB.QueryRow(q, id).Scan(&x))

func Missing

func Missing(err error) error

Missing classifies a single-row read's absence: sql.ErrNoRows becomes a fault.NotFound that still matches sql.ErrNoRows, and any other error or nil passes through. Use it where an owner reads a record by its identity, never after a write: a write that returns no row was not recorded, which is a failure, not an absence.

func OpenRaw

func OpenRaw(url string) (*sql.DB, error)

OpenRaw is a plain connection without schema changes, for readiness waits.

func QueryError

func QueryError(err error, q string) error

func Rebind

func Rebind(query string) string

Rebind turns `?` placeholders into `$1`, `$2`, …, skipping single-quoted strings (” escapes included), `--` line comments and dollar-quoted strings. This adapter serves the legacy DB/Tx methods. Native PostgreSQL queries use SQL() directly, including queries with JSON ? operators.

func Transact

func Transact[T any](ctx context.Context, db *DB, fn func(*Tx) (T, error)) (T, error)

Transact publishes a result only after its writes commit. An error never returns an uncommitted receipt that a caller could accidentally dispatch.

Types

type DB

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

DB owns the PostgreSQL connection pool and rebinds ? placeholders to $n. Concurrency is controlled by transactions, row locks and conditional writes. Close result sets before issuing another query to avoid exhausting the pool. Values are never rewritten: binary content belongs in bytea, not TEXT.

func Open

func Open(url string) (*DB, error)

Open opens and checks a pool without applying application schema or data.

func OpenWith

func OpenWith(url string, dial pgconn.DialFunc) (*DB, error)

OpenWith is Open with every connection made by dial (nil is the default dialer). The test database harness gives its own, which closes connections without leaving them waiting in TIME_WAIT.

func Wrap

func Wrap(pool *sql.DB) *DB

Wrap adopts an existing pool. It does not migrate, seed or open another pool.

func (*DB) Begin

func (d *DB) Begin(ctx context.Context) (*Tx, error)

func (*DB) Close

func (d *DB) Close() error

func (*DB) Exec

func (d *DB) Exec(query string, args ...any) (sql.Result, error)

func (*DB) FailNextStatement

func (d *DB) FailNextStatement(fragment string) func()

FailNextStatement scopes a one-shot fault to this pool and its transactions. The returned cleanup only clears this installation, never a newer one.

func (*DB) FailStatementAfter

func (d *DB) FailStatementAfter(fragment string, skip int) func()

FailStatementAfter lets skip matching statements run, then fails the next one. Use it when an earlier read of the same query is not the one a test is about.

func (*DB) FailStatements

func (d *DB) FailStatements(fragment string, n int) func()

FailStatements fails the next n statements containing fragment: a fault that outlasts a caller's retries.

func (*DB) HoldExclusive

func (d *DB) HoldExclusive(ctx context.Context, key int64) (release func(), err error)

HoldExclusive takes a Postgres session-level advisory lock on this database under key and keeps the one connection that holds it until release is called (or the process ends). It never waits: a lock another session holds is ErrHeldElsewhere at once. The lock belongs to that connection, so a lost connection (a Postgres restart, a network cut) releases it without telling the holder; callers name that as accepted.

func (*DB) InTx

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

func (*DB) Ping

func (d *DB) Ping() error

func (*DB) Pool

func (d *DB) Pool() *sql.DB

Pool is for infrastructure adapters such as River and schema installation. Domain queries use SQL so they retain the checked query boundary.

func (*DB) Query

func (d *DB) Query(query string, args ...any) (*Rows, error)

func (*DB) QueryRow

func (d *DB) QueryRow(query string, args ...any) *Row

func (*DB) ReadSnapshot

func (d *DB) ReadSnapshot(ctx context.Context) (*Tx, error)

ReadSnapshot keeps related read-only facts at one database revision.

func (*DB) SQL

func (d *DB) SQL() Handle

type DBTX

type DBTX interface {
	ExecContext(context.Context, string, ...any) (sql.Result, error)
	PrepareContext(context.Context, string) (*sql.Stmt, error)
	QueryContext(context.Context, string, ...any) (*sql.Rows, error)
	QueryRowContext(context.Context, string, ...any) *sql.Row
}

type Handle

type Handle struct {
	DBTX
	// contains filtered or unexported fields
}

func (Handle) ExecContext

func (d Handle) ExecContext(ctx context.Context, q string, args ...any) (sql.Result, error)

func (Handle) QueryContext

func (d Handle) QueryContext(ctx context.Context, q string, args ...any) (*sql.Rows, error)

func (Handle) QueryRowContext

func (d Handle) QueryRowContext(ctx context.Context, q string, args ...any) *sql.Row

func (Handle) WithExecutor

func (d Handle) WithExecutor(executor DBTX) Handle

WithExecutor decorates statement execution while retaining this handle's fault scope. It is used by query-budget tests and other infrastructure instrumentation.

type Queryer

type Queryer interface{ SQL() Handle }

Generated queries use database/sql directly, on the same pool or transaction as handwritten queries. Keep failure injection on this boundary too, so migrating a write cannot silently bypass the atomicity tests.

type Row

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

Row is a single-row result whose errors name their statement.

func (*Row) Err

func (r *Row) Err() error

func (*Row) Scan

func (r *Row) Scan(dst ...any) error

type Rows

type Rows struct {
	*sql.Rows
	// contains filtered or unexported fields
}

Rows is a result set whose errors name their statement. Close reports an iteration error the caller never asked about, so a loop that ended early is at least loud.

func (*Rows) Close

func (r *Rows) Close() error

func (*Rows) Err

func (r *Rows) Err() error

type Tx

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

func (*Tx) Commit

func (t *Tx) Commit() error

func (*Tx) Exec

func (t *Tx) Exec(query string, args ...any) (sql.Result, error)

func (*Tx) Native

func (t *Tx) Native() *sql.Tx

func (*Tx) Query

func (t *Tx) Query(query string, args ...any) (*Rows, error)

func (*Tx) QueryRow

func (t *Tx) QueryRow(query string, args ...any) *Row

func (*Tx) Rollback

func (t *Tx) Rollback() error

func (*Tx) SQL

func (t *Tx) SQL() Handle

Jump to

Keyboard shortcuts

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