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 ¶
- Variables
- func PluginMigrationChecksum(m storage.PluginMigration) string
- type Migration
- type MigrationStatus
- type Migrator
- type PluginMigrationStatus
- type PluginMigrator
- func (m *PluginMigrator) Apply(ctx context.Context) error
- func (m *PluginMigrator) ApplyPlan(ctx context.Context, plan storage.MigrationPlan) error
- func (m *PluginMigrator) Check(ctx context.Context) error
- func (m *PluginMigrator) Plan(ctx context.Context) (storage.MigrationPlan, error)
- func (m *PluginMigrator) Status(ctx context.Context) ([]PluginMigrationStatus, error)
- type PluginTx
- type Store
- func (s *Store) AuditEvents(ctx context.Context, q storage.AuditQuery) ([]storage.AuditEvent, error)
- func (*Store) Capabilities() storage.Capabilities
- func (s *Store) Check(ctx context.Context) error
- func (s *Store) CheckPlugins(ctx context.Context, schemas []storage.PluginSchema) error
- func (s *Store) ClaimDelivery(ctx context.Context) (storage.Delivery, error)
- func (s *Store) CleanupDeliveries(ctx context.Context, limit int) (int64, error)
- func (s *Store) ConsumeAbuse(ctx context.Context, budgets []storage.AbuseBudget) (time.Duration, error)
- func (s *Store) FinishDelivery(ctx context.Context, id string, attempt int, delivered bool) error
- func (s *Store) LiveDeliveries(ctx context.Context, afterID string, limit int) ([]storage.Delivery, error)
- func (s *Store) PruneAuditEvents(ctx context.Context, before time.Time, limit int) (int64, error)
- func (s *Store) PruneExpired(ctx context.Context, before time.Time, limit int) (storage.Pruned, error)
- func (s *Store) RecordAuditEvent(ctx context.Context, e storage.AuditEvent) error
- func (s *Store) ReplaceDeliveryPayload(ctx context.Context, id string, expected, replacement storage.Material) error
- func (s *Store) WithinTx(ctx context.Context, fn func(storage.Tx) error) error
Constants ¶
This section is empty.
Variables ¶
var ( ErrSchema = errors.New("postgres: incompatible or altered core schema") ErrPending = errors.New("postgres: core migrations pending") 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.
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 ¶
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 (*Migrator) Apply ¶
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.
type PluginMigrationStatus ¶
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 (*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) Plan ¶
func (m *PluginMigrator) Plan(ctx context.Context) (storage.MigrationPlan, error)
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 ¶
func (m *PluginMigrator) Status(ctx context.Context) ([]PluginMigrationStatus, error)
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.
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 (*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 ¶
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 (*Store) ClaimDelivery ¶
func (*Store) CleanupDeliveries ¶
func (*Store) ConsumeAbuse ¶
func (*Store) FinishDelivery ¶
func (*Store) LiveDeliveries ¶
func (*Store) PruneAuditEvents ¶
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.