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

migrate

package
v0.5.3 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package migrate declares immutable, versioned schema changes and validates migration history. Models describe current types; these definitions preserve historical changes and are never inferred or applied during application boot.

Index

Constants

View Source
const MaxRollbackSteps = 1000

MaxRollbackSteps bounds one explicit rollback.

Variables

View Source
var ErrReconciliationRequired = safeerror.New("nontransactional migration requires reconciliation")

Functions

This section is empty.

Types

type Applied

type Applied struct {
	Key       Key       `json:"key"`
	Version   Version   `json:"version"`
	Checksum  Checksum  `json:"checksum"`
	Batch     int64     `json:"batch"`
	AppliedAt time.Time `json:"applied_at"`
}

Applied records a completed migration. Nontransactional statements finish before their history entry; their effects are not atomic with history.

type Checksum

type Checksum [32]byte

Checksum is the SHA-256 identity of a complete migration definition.

func ParseChecksum

func ParseChecksum(text string) (Checksum, error)

ParseChecksum requires the exact lowercase hexadecimal history representation.

func (Checksum) MarshalText

func (c Checksum) MarshalText() ([]byte, error)

MarshalText returns the checksum's lowercase hexadecimal bytes.

func (Checksum) String

func (c Checksum) String() string

String returns the checksum's lowercase hexadecimal representation.

func (*Checksum) UnmarshalText

func (c *Checksum) UnmarshalText(text []byte) error

UnmarshalText parses the exact lowercase hexadecimal representation and replaces the checksum on success. A nil receiver returns fault.Invalid.

type Definition

type Definition struct {
	Mode     ExecutionMode
	Key      Key
	Version  Version
	SQL      []string
	Down     []string
	Requires []Key
}

Definition is the handwritten or generated source of an immutable migration. SQL entries execute in order using Mode (transactional by default). Requires references declared migrations; New snapshots all slices and computes hashes.

Down optionally reverses the migration for an explicit Postgres.Rollback. It is excluded from the checksum, so adding or correcting Down never drifts applied history, and it must be valid inside one transaction: a nontransactional migration cannot declare Down. Without Down a migration is irreversible and rollback refuses to cross it.

func (Definition) Clone

func (d Definition) Clone() Definition

Clone returns a copy that shares no SQL, Down or Requires storage with d. Use it wherever a caller-owned definition is snapshotted before New.

type Entry

type Entry struct {
	Mode       ExecutionMode `json:"mode,omitempty"`
	Key        Key           `json:"key"`
	Version    Version       `json:"version"`
	Checksum   Checksum      `json:"checksum"`
	Requires   []Key         `json:"requires,omitempty"`
	Reversible bool          `json:"reversible,omitempty"`
}

Entry is immutable migration metadata, returned as a caller-owned snapshot. Checksum covers origin, ID, introduced version, ordered SQL and dependencies.

type ExecutionMode

type ExecutionMode string

ExecutionMode selects atomic execution or individually journaled statements. The zero value preserves the historical transactional checksum and behavior.

const (
	Transactional    ExecutionMode = ""
	NonTransactional ExecutionMode = "nontransactional"
)

type ID

type ID string

ID is a stable migration identifier within an origin. Sortable numeric prefixes are conventional, but explicit Requires dependencies take precedence.

type InterruptedMigration

type InterruptedMigration struct {
	Progress Progress
	// contains filtered or unexported fields
}

InterruptedMigration retains the checkpoint and cause of an interrupted nontransactional migration. Inspect database state before reconciling an uncertain statement.

func (*InterruptedMigration) Error

func (*InterruptedMigration) Error() string

Error returns a fixed reconciliation message without formatting the cause.

func (*InterruptedMigration) Is

func (*InterruptedMigration) Is(target error) bool

Is reports whether target is ErrReconciliationRequired.

func (*InterruptedMigration) Unwrap

func (e *InterruptedMigration) Unwrap() error

Unwrap returns the retained interruption cause.

type Key

type Key struct {
	Origin Origin `json:"origin"`
	ID     ID     `json:"id"`
}

Key identifies one migration without ambiguous delimiter concatenation.

type Origin

type Origin string

Origin identifies the application, framework, or plugin owning a migration.

type Postgres

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

Postgres is an explicit PostgreSQL migration runner over Foundry's DB. Creating it performs no I/O. Status never creates a history table; Up is the only schema mutation entry point. There is no reset, wipe, or automatic synchronization.

func NewPostgres

func NewPostgres(db *database.DB, registry *Registry, config PostgresConfig) (*Postgres, error)

NewPostgres binds an immutable registry and the intended history namespace. The supplied DB must connect to PostgreSQL; protocol fixtures do not certify a different database's compatibility with PostgreSQL SQL and advisory locks.

func (*Postgres) Reconcile

func (p *Postgres) Reconcile(ctx context.Context, expected Progress, outcome StatementOutcome) (Progress, error)

Reconcile records an operator-verified outcome for exactly the inspected uncertain statement under the runner's advisory lock. It executes no migration SQL. Inspect the catalog/data first; a wrong attestation can lose/repeat effects. Up then resumes from the resulting checkpoint. Stale snapshots fail closed.

func (*Postgres) Registry

func (p *Postgres) Registry() *Registry

Registry returns the immutable registry this runner applies.

func (*Postgres) Rollback

func (p *Postgres) Rollback(ctx context.Context, steps int) (result RollbackResult, err error)

Rollback reverses the last steps applied migrations, newest first, each in its own transaction that runs the Down SQL and removes its history entry. It holds the migration lock and refuses before changing anything when history has drifted or awaits reconciliation, when a selected migration has no Down SQL, or when a migration outside the selection depends on one inside it. Earlier reversals stay committed if a later one fails. Rollback is an explicit operator action; it never runs during boot or migrate up.

func (*Postgres) RollbackPlan

func (p *Postgres) RollbackPlan(ctx context.Context, steps int) ([]Applied, error)

RollbackPlan reports, without locking or changing anything, the last steps applied migrations that Rollback would reverse, newest first. It returns an error naming the obstacle when that rollback would be refused.

func (*Postgres) Status

func (p *Postgres) Status(ctx context.Context) (Report, error)

Status reads committed history and reports definition drift. A missing table produces pending definitions without creating schemas, tables, or locks.

func (*Postgres) Up

func (p *Postgres) Up(ctx context.Context) (result RunResult, err error)

Up holds one session advisory lock across history validation and all pending migrations. Transactional definitions and history commit atomically; explicitly nontransactional statements use a durable progress journal. An uncertain step blocks further execution until explicit reconciliation. In both modes, earlier successful migrations remain committed if a later migration fails. A new call inspects history again under the lock. No callback is blindly retried.

type PostgresConfig

type PostgresConfig struct {
	Schema               string
	Table                string
	LockTimeout          time.Duration
	LockPollInterval     time.Duration
	CleanupTimeout       time.Duration
	MaxHistory           int
	StatementLockTimeout time.Duration
	StatementTimeout     time.Duration
	SearchPath           string
}

PostgresConfig owns a migration history namespace and resource bounds. The schema/table must be simple PostgreSQL identifiers of at most 63 ASCII bytes. All cooperating runners must use the same history schema and table.

LockTimeout bounds acquisition of the runner's advisory lock. Up also sets PostgreSQL's lock_timeout to StatementLockTimeout for its session, so DDL that cannot obtain a table lock fails instead of queueing behind long transactions and blocking application traffic; a transactional migration then rolls back and can be retried. StatementTimeout sets statement_timeout for the session; zero disables it, so long migrations are not canceled by an application pool limit. SearchPath, when set, makes that one schema (then pg_temp) the session search_path, so unqualified migration SQL creates and alters objects in it; empty keeps the connection's own path. All settings are restored before the connection returns to the pool. History and progress tables are always schema-qualified.

func DefaultPostgresConfig

func DefaultPostgresConfig() PostgresConfig

DefaultPostgresConfig returns the foundry_ops.schema_migrations namespace and default runner limits. Statement timeout is disabled and the connection's search path is retained.

func (PostgresConfig) Validate

func (c PostgresConfig) Validate() error

Validate checks identifiers and runner limits, returning fault.Invalid for unsupported settings.

type Problem

type Problem struct {
	Code       ProblemCode `json:"code"`
	Key        Key         `json:"key"`
	Dependency *Key        `json:"dependency,omitempty"`
}

Problem identifies history drift without including migration SQL or values.

type ProblemCode

type ProblemCode string

ProblemCode names a specific history conflict that prevents an up operation.

const (
	ReconciliationRequired ProblemCode = "reconciliation_required"
	ProgressMismatch       ProblemCode = "progress_mismatch"
	DefinitionChanged      ProblemCode = "definition_changed"
	DefinitionMissing      ProblemCode = "definition_missing"
	DependencyNotApplied   ProblemCode = "dependency_not_applied"
)

type Progress

type Progress struct {
	Key       Key       `json:"key"`
	Version   Version   `json:"version"`
	Checksum  Checksum  `json:"checksum"`
	Batch     int64     `json:"batch"`
	Confirmed int       `json:"confirmed_statements"`
	State     StepState `json:"state"`
	Revision  int64     `json:"revision"`
	UpdatedAt time.Time `json:"updated_at"`
}

Progress is a durable nontransactional checkpoint. Confirmed counts statements with a successfully recorded result. InFlight/Uncertain never authorize retry. Revision protects reconciliation against a stale inspection snapshot.

type Registry

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

Registry owns validated definitions in deterministic dependency order. It is safe to share across goroutines; returned metadata and plans are copies.

func New

func New(definitions ...Definition) (*Registry, error)

New validates definitions before any database operation. Duplicate keys, invalid dependencies, and cycles are errors. Independent nodes sort by ID, then origin. Dependency lists are canonicalized; SQL ordering is preserved.

func (*Registry) Definition

func (r *Registry) Definition(key Key) (Definition, bool)

Definition returns an owned copy of a registered definition, including its SQL and Down statements, for read-only inspection such as migrate show.

func (*Registry) Entries

func (r *Registry) Entries() []Entry

Entries returns metadata in execution order without exposing owned slices.

func (*Registry) Inspect

func (r *Registry) Inspect(history []Applied) (Report, error)

Inspect validates a history snapshot and reports missing/changed definitions and dependencies. It performs no database I/O and does not repair history.

func (*Registry) Pending

func (r *Registry) Pending(history []Applied) ([]Entry, error)

Pending returns execution metadata only if the entire history is consistent. It is a snapshot, not a lock or authorization to execute an old plan; a runner must inspect history again while holding its database migration lock.

type Report

type Report struct {
	Statuses  []Status  `json:"migrations"`
	Problems  []Problem `json:"problems,omitempty"`
	LastBatch int64     `json:"last_batch"`
}

Report is a caller-owned status snapshot. Problems may be shown by read-only status commands; Check must succeed before applying any pending definitions.

func (Report) Check

func (r Report) Check() error

Check reports drift without formatting untrusted SQL or stored values.

type RollbackResult

type RollbackResult struct {
	RolledBack  []Applied `json:"rolled_back"`
	Interrupted *Key      `json:"interrupted,omitempty"`
}

RollbackResult lists migrations whose reversal committed, newest first. Interrupted names the attempted reversal lacking a successful confirmation; it may have committed when the returned database outcome is Unknown.

type RunResult

type RunResult struct {
	Batch       int64     `json:"batch"`
	Applied     []Applied `json:"applied"`
	Interrupted *Key      `json:"interrupted,omitempty"`
}

RunResult preserves migrations known to have committed before a later failure. Interrupted names the attempted migration lacking a successful confirmation; it may have committed when the returned database outcome is Unknown.

type State

type State string

State is a migration's status relative to the currently registered definitions.

const (
	Pending    State = "pending"
	Incomplete State = "incomplete"
	Complete   State = "applied"
	Changed    State = "changed"
	Missing    State = "missing_definition"
)

type StatementOutcome

type StatementOutcome string

StatementOutcome is an operator's explicit attestation after inspecting actual database state. Foundry does not infer whether an interrupted statement ran.

const (
	StatementApplied    StatementOutcome = "applied"
	StatementNotApplied StatementOutcome = "not_applied"
)

type Status

type Status struct {
	Progress   *Progress `json:"progress,omitempty"`
	Key        Key       `json:"key"`
	State      State     `json:"state"`
	Definition *Entry    `json:"definition,omitempty"`
	Applied    *Applied  `json:"applied,omitempty"`
}

Status contains current metadata and, when present, its recorded history.

type StepState

type StepState string

StepState identifies a nontransactional migration statement's durable checkpoint state.

const (
	StepReady     StepState = "ready"
	StepInFlight  StepState = "in_flight"
	StepUncertain StepState = "uncertain"
)

type Version

type Version string

Version records the release that introduced a migration, not the currently installed framework/plugin version. Changing it changes historical identity.

Jump to

Keyboard shortcuts

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