postgres

package
v0.30.1 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2026 License: MIT Imports: 26 Imported by: 13

Documentation

Index

Constants

View Source
const (
	// PingTimeout bounds how long Ping keeps retrying before giving up.
	PingTimeout = 10 * time.Second
	// PingRetryInterval is the wait between failed ping attempts, keeping Ping
	// from tight-looping reconnects on an unreachable database.
	PingRetryInterval = 100 * time.Millisecond
)
View Source
const NameLen = 31

NameLen caps the length of a generated schema or database name, keeping it within PostgreSQL's 63-byte identifier limit with room for prefixes.

Variables

View Source
var ErrNoDbInContext = errors.New("context does not contain a bun.DB")

ErrNoDbInContext is returned by RunMigrationsContext when the context carries a bun.IDB that is not a full *bun.DB, which migrations require. ErrNoIDBInContext covers the case of no connection at all.

View Source
var ErrNoIDBInContext = errors.New("context does not contain a bun.IDB")

ErrNoIDBInContext is returned by GetContext when the context carries no bun.IDB, meaning it was never seeded by NewContext or one of its variants. ErrNoDbInContext covers the stricter case where a connection is present but is not a full *bun.DB.

View Source
var ErrUnsupportedSchemaObject = errors.New("schema holds an object class the census cannot render")

ErrUnsupportedSchemaObject reports a schema object the census cannot safely compare. Such objects fail instead of being silently omitted.

Functions

func GetContext

func GetContext(ctx context.Context) (bun.IDB, error)

GetContext returns the bun.IDB stored in ctx by NewContext or one of its variants, or ErrNoIDBInContext when none is present.

func InTx added in v0.23.0

func InTx(ctx context.Context) bool

InTx reports whether ctx carries an open transaction. It reports false when ctx carries the connection pool, and false when it carries no database at all.

Work that must not hold a pooled connection — any call to an external service — guards itself with this.

It reports true under RunTransactionalTest, whose PassthroughTx is not a *bun.DB. A test covering an outbound call must therefore use RunDBTest, which puts a real pool on the context.

func NewContext

func NewContext(ctx context.Context, config Config) (context.Context, error)

NewContext derives a context carrying a connection to the primary database, for later retrieval with GetContext.

func NewContextSchema

func NewContextSchema(ctx context.Context, config Config, schema string, create bool) (context.Context, error)

NewContextSchema derives a context carrying a connection scoped to the named schema, creating the schema first when create is true.

func NewContextTest

func NewContextTest(ctx context.Context, config Config) (context.Context, string, error)

NewContextTest derives a context bound to a fresh, randomly named schema created through config, isolating the test from others sharing the database. It returns the schema name so the caller can drop it once done.

func Ping

func Ping(ctx context.Context, client *bun.DB) error

Ping a database connection until it succeeds or the timeout is reached. Honors ctx cancellation both for the PingContext call and for the wait between retries.

func RunDBTest added in v0.22.0

func RunDBTest(t *testing.T, config Config, migrations fs.FS, callback TransactionalTestFunc)

RunDBTest runs callback against its own freshly created PostgreSQL database, cloned from a migrated template via `CREATE DATABASE … TEMPLATE`. Every call is physically isolated, so the caller may mark the test and its sub-tests t.Parallel() even when they reuse the same fixture keys.

The cost model is "migrate once, clone many": the migration set is applied a single time into a template database whose name is a hash of the migrations, and each test gets a fast file-level copy of it. The per-test database is dropped (WITH FORCE) in t.Cleanup; the template is left in place and reused across runs as long as the migrations are unchanged.

config must expose Options() []pgdriver.Option (postgrespresets.Default does). callback receives a context carrying a real *bun.DB for the per-test database, retrievable with GetContext.

func RunIsolatedTransactionalTest

func RunIsolatedTransactionalTest(t *testing.T, config Config, migrations fs.FS, callback TransactionalTestFunc)

RunIsolatedTransactionalTest runs callback in a throwaway schema, which admits operations a transaction cannot host concurrently, such as refreshing a materialized view.

The schema lives in the existing database, so its extensions remain available. Each call reruns the whole migration set, which makes RunTransactionalTest the cheaper default.

func RunMigrationRoundtripTest added in v0.30.0

func RunMigrationRoundtripTest(t *testing.T, config Config, migrations fs.FS, opts *RoundtripOptions)

RunMigrationRoundtripTest proves that every down migration exactly reverses its up.

It snapshots each up, verifies each down against the preceding snapshot, then re-applies the full set. Fixtures run between steps. Snapshots bind each schema to its exact migration prefix.

config must expose Options() []pgdriver.Option, as postgrespresets.Default does.

func RunMigrations

func RunMigrations(ctx context.Context, db *bun.DB, migrations fs.FS) error

RunMigrations runs all the migrations found in the provided filesystem.

func RunMigrationsContext

func RunMigrationsContext(ctx context.Context, migrations fs.FS) error

RunMigrationsContext runs all the migrations found in the provided filesystem, using the database connection from the context.

func RunTransactionalTest

func RunTransactionalTest(t *testing.T, config Config, callback TransactionalTestFunc)

RunTransactionalTest runs callback inside a transaction that is rolled back on cleanup. The context carries a PassthroughTx, which discards sub-transactions so concurrent calls sharing the connection cannot deadlock.

func SchemaSnapshot added in v0.30.0

func SchemaSnapshot(ctx context.Context, db bun.IDB, schema string) (string, error)

SchemaSnapshot renders supported schema objects as canonical, sorted, one-line records. PostgreSQL renders definitions, so statement order and DDL spelling do not affect the result.

It includes database-scoped extensions and schemas, reads no row data, and returns ErrUnsupportedSchemaObject rather than omitting an unsupported class.

func SnapshotDelta added in v0.30.0

func SnapshotDelta(want, got string) []string

SnapshotDelta returns sorted per-object differences between want and got. Records are compared as a set.

func TransferContext

func TransferContext(baseCtx, destCtx context.Context) context.Context

TransferContext transfers the current postgres context into another. If the source context is not a postgres context, this is a no-op.

func WithTx added in v0.23.0

func WithTx(ctx context.Context, tx bun.IDB) context.Context

WithTx derives a context carrying tx, so GetContext resolves that transaction.

WithinTx applies this for you and is what callers normally want. WithTx is exported for the cases that own the transaction lifecycle themselves — a test harness wrapping a whole suite, or a caller bridging a transaction it opened through some other API.

func WithinTx added in v0.23.0

func WithinTx(ctx context.Context, opts *sql.TxOptions, callback func(ctx context.Context) error) error

WithinTx runs callback inside a transaction opened on the connection carried by ctx, and installs that transaction on the context callback receives, so every call made with it takes part in the transaction.

The callback takes no transaction argument: the context it receives is the only database handle reachable inside it, so no call can escape unnoticed.

A nested call joins the transaction already in progress, so one unit of work has one outcome and a rollback anywhere discards all of it. A nested call never reaches opts: an operation depending on a specific isolation level must be the outermost transaction.

Types

type Config

type Config interface {
	// DB returns a connection to the primary database, opening it on first call
	// and reusing it thereafter.
	DB(ctx context.Context) (*bun.DB, error)
	// DBSchema returns a connection scoped to the named schema, creating the
	// schema first when create is true. An empty schema name yields the primary
	// connection.
	DBSchema(ctx context.Context, schema string, create bool) (*bun.DB, error)
}

Config supplies pooled bun database connections to the rest of the package. A Config owns the driver options and the connection lifecycle; the context, migration, and test helpers all obtain their handles through it. postgrespresets.Default is the standard implementation.

type ContextKey

type ContextKey struct{}

ContextKey is the context value key under which the package stores the active bun.IDB connection.

type PassthroughTx

type PassthroughTx struct {
	bun.Tx
}

PassthroughTx extends bun.Tx so that a nested transaction call resolves to the same transaction.

PostgreSQL has no nested transactions, so bun opens a savepoint instead. A savepoint belongs to its parent's query stream and cannot serve parallel callers, which breaks a test suite that wraps the whole application in one transaction and then calls a method from several goroutines.

func NewPassthroughTx

func NewPassthroughTx(tx bun.Tx) *PassthroughTx

NewPassthroughTx wraps tx so that nested transaction calls resolve to tx itself.

func (*PassthroughTx) Begin

func (tx *PassthroughTx) Begin() (bun.Tx, error)

func (*PassthroughTx) BeginTx

func (tx *PassthroughTx) BeginTx(_ context.Context, _ *sql.TxOptions) (bun.Tx, error)

func (*PassthroughTx) Commit

func (tx *PassthroughTx) Commit() error

func (*PassthroughTx) Rollback

func (tx *PassthroughTx) Rollback() error

func (*PassthroughTx) RunInTx

func (tx *PassthroughTx) RunInTx(
	ctx context.Context, _ *sql.TxOptions, fn func(ctx context.Context, tx bun.Tx) error,
) error

type RoundtripOptions added in v0.30.0

type RoundtripOptions struct {
	// Fixtures holds optional `<timestamp>_<name>.sql` files, applied after the named migration.
	Fixtures fs.FS

	// Snapshots holds one history-bound schema snapshot per migration. GOLIB_UPDATE_SNAPSHOTS
	// rewrites them.
	Snapshots string
}

RoundtripOptions configures RunMigrationRoundtripTest. Its zero value is valid.

type TransactionalTestFunc

type TransactionalTestFunc func(context.Context, *testing.T)

TransactionalTestFunc is the body of a database-backed test, run with a context carrying the connection isolated for that test.

type Transactor added in v0.23.0

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

A Transactor is the PostgreSQL implementation of github.com/a-novel-kit/golib/transaction.Transactor.

func NewTransactor added in v0.23.0

func NewTransactor(opts *sql.TxOptions) *Transactor

NewTransactor returns a Transactor opening its transactions with opts. A nil opts leaves the database defaults in place, which is read-committed isolation.

func (*Transactor) WithinTx added in v0.23.0

func (transactor *Transactor) WithinTx(ctx context.Context, fn func(ctx context.Context) error) error

WithinTx satisfies github.com/a-novel-kit/golib/transaction.Transactor.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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