postgres

package
v0.1.0-alpha.9 Latest Latest
Warning

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

Go to latest
Published: Sep 23, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package postgres provides explicit versioned core PostgreSQL migrations and the transactional storage.Store adapter over them. Startup checks never apply DDL. See docs/postgres-adapter.md. The adapter passes the reusable gate in storage/conformance, which is what defines a correct adapter.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrSchema        = errors.New("postgres: incompatible or altered core schema")
	ErrPending       = errors.New("postgres: core migrations pending")
	ErrUnavailable   = errors.New("postgres: migration database unavailable")
	ErrCommitUnknown = errors.New("postgres: migration commit outcome unknown; inspect status before retrying")
	ErrConfig        = errors.New("postgres: invalid migration configuration")
)

Migration errors never expose driver errors, SQL or connection credentials.

View Source
var (
	ErrPluginSchema  = errors.New("postgres: incompatible plugin schema, history or ownership")
	ErrPluginPending = errors.New("postgres: plugin migrations pending")
)

Functions

func PluginMigrationChecksum

func PluginMigrationChecksum(m storage.PluginMigration) string

PluginMigrationChecksum is the hex SHA-256 of a plugin migration's SQL, the value auth_plugin_migrations records and compares byte for byte.

Types

type Migration

type Migration struct {
	Version  int
	Name     string
	SQL      string
	Checksum string
}

Migration is one embedded core migration as the operator CLI exports it for review: the manifest position, the file name, the exact SQL and the hex SHA-256 of those bytes that the history table records.

func Migrations

func Migrations() []Migration

Migrations returns the embedded core migrations in manifest order. It reads no database; Apply is the only way to execute them with history rows.

type MigrationStatus

type MigrationStatus struct{ Version, Latest int }

MigrationStatus describes a validated contiguous history. Version zero is an empty schema. Pending versions require explicit Apply; Check never applies DDL.

type Migrator

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

Migrator borrows a PostgreSQL database/sql pool (for example pgx/stdlib). It does not close it. The operator must create the selected schema beforehand. All operations require a bounded context; schema DDL uses a separate operator role.

func NewMigrator

func NewMigrator(db *sql.DB, schema string) (*Migrator, error)

func (*Migrator) Apply

func (m *Migrator) Apply(ctx context.Context) error

Apply atomically installs all pending migrations and their history. A failed or interrupted transaction leaves the previous version intact. No down/force or history repair operation is provided.

func (*Migrator) Check

func (m *Migrator) Check(ctx context.Context) error

Check is a read-only startup check: only the latest exact schema is supported.

func (*Migrator) Status

func (m *Migrator) Status(ctx context.Context) (MigrationStatus, error)

type PluginMigrationStatus

type PluginMigrationStatus struct {
	ID              string
	Version, Latest int
}

type PluginMigrator

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

PluginMigrator snapshots a compiled registry, without accessing the database. Core migrations must be applied first. All plugin upgrades in one Apply are atomic, ordered by dependencies and serialized with core migration operations. Disabled plugins retain both their objects and ownership/history records.

func NewPluginMigrator

func NewPluginMigrator(db *sql.DB, schema string, registry plugin.Registry) (*PluginMigrator, error)

func (*PluginMigrator) Apply

func (m *PluginMigrator) Apply(ctx context.Context) error

func (*PluginMigrator) ApplyPlan

func (m *PluginMigrator) ApplyPlan(ctx context.Context, plan storage.MigrationPlan) error

ApplyPlan applies a reviewed plan. It refuses with storage.ErrPlanChanged, changing nothing, unless the plan was made by these declarations for this schema and every owner is still at the version the plan recorded; each comparison happens under the exclusive migration lock of the transaction that applies. Core and plugin steps commit in separate transactions, as with Apply: if the plugin batch fails or its plan went stale, applied core versions stay committed and a fresh plan shows the remainder.

func (*PluginMigrator) Check

func (m *PluginMigrator) Check(ctx context.Context) error

func (*PluginMigrator) Plan

Plan returns the inspectable plan of what Apply on the core migrator and then this plugin migrator would execute: pending core versions, then each enabled plugin's pending versions in dependency order. It is read-only, takes the shared migration lock and validates exactly what Apply validates, except that plugins are planned even while core migrations are pending. A registry without plugins plans core alone.

func (*PluginMigrator) Status

type PluginTx

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

PluginTx lets a trusted PostgreSQL plugin repository join a core transaction. It never exposes commit/rollback. SQL and arguments remain plugin-owned; use Table for owned relation names and placeholders for values. This is not a SQL sandbox: never use transaction control, DDL, other owners' mutations or retain this handle beyond the callback. Follow the core user-lock ordering contract.

func BindPluginTx

func BindPluginTx(tx storage.Tx, id string) (*PluginTx, error)

func (*PluginTx) Dialect

func (*PluginTx) Dialect() storage.Dialect

func (*PluginTx) Exec

func (p *PluginTx) Exec(query string, args ...any) (int64, error)

func (*PluginTx) Scan

func (p *PluginTx) Scan(query string, args []any, dest ...any) error

Scan executes one row query without exposing a driver row or driver errors. Missing rows return ErrNotFound without poisoning the transaction.

func (*PluginTx) Table

func (p *PluginTx) Table(name string) (string, error)

type Store

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

Store borrows a host-owned pool. New never connects or migrates; call Check at startup and use deadline-bounded contexts for all transactions.

func New

func New(db *sql.DB, schema string) (*Store, error)

func (*Store) AuditEvents

func (s *Store) AuditEvents(ctx context.Context, q storage.AuditQuery) ([]storage.AuditEvent, error)

func (*Store) Capabilities

func (*Store) Capabilities() storage.Capabilities

func (*Store) Check

func (s *Store) Check(ctx context.Context) error

Check reports migration status directly: ErrPending and ErrSchema are safe, documented operator diagnostics, and the migrator already sanitizes driver failures into ErrUnavailable or the context error. StartupCheck still collapses every failure into storage.ErrUnavailable at the service boundary.

func (*Store) CheckPlugins

func (s *Store) CheckPlugins(ctx context.Context, schemas []storage.PluginSchema) error

func (*Store) ClaimDelivery

func (s *Store) ClaimDelivery(ctx context.Context) (storage.Delivery, error)

func (*Store) CleanupDeliveries

func (s *Store) CleanupDeliveries(ctx context.Context, limit int) (int64, error)

func (*Store) ConsumeAbuse

func (s *Store) ConsumeAbuse(ctx context.Context, budgets []storage.AbuseBudget) (time.Duration, error)

func (*Store) FinishDelivery

func (s *Store) FinishDelivery(ctx context.Context, id string, attempt int, delivered bool) error

func (*Store) LiveDeliveries

func (s *Store) LiveDeliveries(ctx context.Context, afterID string, limit int) ([]storage.Delivery, error)

func (*Store) PruneAuditEvents

func (s *Store) PruneAuditEvents(ctx context.Context, before time.Time, limit int) (int64, error)

func (*Store) PruneExpired

func (s *Store) PruneExpired(ctx context.Context, before time.Time, limit int) (storage.Pruned, error)

PruneExpired runs one bounded DELETE per table. Each statement selects its victims with FOR UPDATE SKIP LOCKED so concurrent pruners and live operations never wait on each other, and clamps the cutoff to database time so a caller's clock can never remove a row that is still usable.

func (*Store) RecordAuditEvent

func (s *Store) RecordAuditEvent(ctx context.Context, e storage.AuditEvent) error

func (*Store) ReplaceDeliveryPayload

func (s *Store) ReplaceDeliveryPayload(ctx context.Context, id string, expected, replacement storage.Material) error

func (*Store) WithinTx

func (s *Store) WithinTx(ctx context.Context, fn func(storage.Tx) error) error

Jump to

Keyboard shortcuts

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