migration

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 24, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrDuplicateVersion   = errors.New("migration: duplicate version")
	ErrDuplicateName      = errors.New("migration: duplicate name")
	ErrDirtyState         = errors.New("migration: dirty state")
	ErrChecksumMismatch   = errors.New("migration: checksum mismatch")
	ErrLockTimeout        = errors.New("migration: lock timeout")
	ErrUnsupportedDialect = errors.New("migration: unsupported dialect")
	ErrPendingMigration   = errors.New("migration: pending migration")
	ErrStateCorrupted     = errors.New("migration: state corrupted")
	ErrTargetMismatch     = errors.New("migration: target mismatch")
	ErrInvalidConfig      = errors.New("migration: invalid config")
	ErrUnsupportedDriver  = errors.New("migration: unsupported driver")
	ErrMissingChecksum    = errors.New("migration: missing checksum")
	ErrInvalidMigration   = errors.New("migration: invalid migration")
)

Functions

func Commands

func Commands(app foundation.Application) []*cobra.Command

Commands returns migration CLI commands bound to the application DI container.

func ComputeFingerprint

func ComputeFingerprint(in FingerprintInput) string

ComputeFingerprint returns sha256:... of normalized identity.

func FingerprintFromDBOptions

func FingerprintFromDBOptions(opt db.Options) string

FingerprintFromDBOptions builds a fingerprint from db.Options without secrets.

func FormatPlanItem

func FormatPlanItem(item PlanItem) string

FormatPlanItem returns a stable status line.

func LockKey

func LockKey(namespace, connection, fingerprint string) string

LockKey builds a lock key from target components.

func ShortFingerprint

func ShortFingerprint(fp string) string

ShortFingerprint returns a log-safe short id.

func ValidatePlan

func ValidatePlan(plan Plan, requireNoPending bool) error

ValidatePlan returns an error if plan has dirty/mismatch/pending when required.

Types

type ConnectionOptions

type ConnectionOptions struct {
	Enabled bool `json:"enabled"`
}

ConnectionOptions enables a named connection.

type Error

type Error struct {
	Op  string
	Err error
	Msg string
}

Error wraps a sentinel with context.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Unwrap

func (e *Error) Unwrap() error

type FileLocker

type FileLocker struct {
	Root    string
	Timeout time.Duration
}

FileLocker uses OS file locks for single-host mutual exclusion.

func NewFileLocker

func NewFileLocker(root string, timeout time.Duration) (*FileLocker, error)

NewFileLocker creates a file locker under root.

func (*FileLocker) Lock

func (l *FileLocker) Lock(ctx context.Context, key string) (func() error, error)

Lock acquires an exclusive lock for key.

type FileStateStore

type FileStateStore struct {
	Root string
}

FileStateStore stores migration state as JSON under a root directory.

func NewFileStateStore

func NewFileStateStore(root string) (*FileStateStore, error)

NewFileStateStore creates a file-backed state store.

func (*FileStateStore) Load

func (s *FileStateStore) Load(ctx context.Context, key TargetKey) (Snapshot, error)

Load reads the snapshot for the target key.

func (*FileStateStore) MarkApplied

func (s *FileStateStore) MarkApplied(ctx context.Context, key TargetKey, record Record) error

MarkApplied records a successful migration.

func (*FileStateStore) MarkFailed

func (s *FileStateStore) MarkFailed(ctx context.Context, key TargetKey, record Record, cause error) error

MarkFailed records a failed migration.

func (*FileStateStore) MarkRunning

func (s *FileStateStore) MarkRunning(ctx context.Context, key TargetKey, record Record) error

MarkRunning records a migration as running.

type FingerprintInput

type FingerprintInput struct {
	Driver   string
	Host     string
	Port     int
	Database string
	Schema   string
}

FingerprintInput holds safe connection identity fields (never password/DSN).

type LockOptions

type LockOptions struct {
	Driver string `json:"driver"`
}

LockOptions configures the locker.

type Locker

type Locker interface {
	Lock(ctx context.Context, key string) (unlock func() error, err error)
}

Locker provides exclusive access for a migration target.

type Migration

type Migration interface {
	Version() uint64
	Name() string
	Mode() Mode
	Scope() Scope
	Connection() string
	Up(ctx context.Context, db *gorm.DB) error
}

Migration describes a single migration definition.

type Mode

type Mode string

Mode distinguishes versioned vs repeatable migrations.

const (
	ModeVersioned  Mode = "versioned"
	ModeRepeatable Mode = "repeatable"
)

type Options

type Options struct {
	Enabled     bool                         `json:"enabled"`
	StartupMode StartupMode                  `json:"startup-mode"`
	FailFast    bool                         `json:"fail-fast"`
	Transaction TransactionMode              `json:"transaction"`
	LockTimeout string                       `json:"lock-timeout"`
	State       StateOptions                 `json:"state"`
	Lock        LockOptions                  `json:"lock"`
	Connections map[string]ConnectionOptions `json:"connections"`
	// contains filtered or unexported fields
}

Options is loaded from conf/migration.yaml.

func (Options) LockTimeoutDuration

func (o Options) LockTimeoutDuration() time.Duration

LockTimeoutDuration returns parsed lock timeout.

type Plan

type Plan struct {
	Namespace         string
	Connection        string
	TargetFingerprint string
	Dirty             bool
	Items             []PlanItem
	Executable        []PlanItem
	Problems          []PlanItem
}

Plan is the result of comparing registry with snapshot.

func BuildPlan

func BuildPlan(reg *Registry, snap Snapshot, connection, fingerprint string) (Plan, error)

BuildPlan compares registry and snapshot.

func (Plan) HasProblems

func (p Plan) HasProblems() bool

HasProblems reports blocking issues.

func (Plan) PendingCount

func (p Plan) PendingCount() int

PendingCount returns how many migrations would run.

type PlanItem

type PlanItem struct {
	Kind        PlanItemKind
	Identity    string
	Version     uint64
	Name        string
	Mode        Mode
	Scope       Scope
	Checksum    string
	OldChecksum string
	Status      Status
	Error       string
}

PlanItem is one entry in a migration plan.

type PlanItemKind

type PlanItemKind string

PlanItemKind classifies a planned action.

const (
	PlanPending           PlanItemKind = "pending"
	PlanRepeatableChanged PlanItemKind = "repeatable_changed"
	PlanApplied           PlanItemKind = "applied"
	PlanChecksumMismatch  PlanItemKind = "checksum_mismatch"
	PlanDirty             PlanItemKind = "dirty"
)

type ProviderOption

type ProviderOption func(*ServiceProvider)

ProviderOption configures MigrationServiceProvider.

func WithChecksums

func WithChecksums(checksums map[string]string) ProviderOption

WithChecksums supplies checksum manifest generated by migration:generate.

func WithMigrations

func WithMigrations(migrations ...Migration) ProviderOption

WithMigrations registers migration definitions.

func WithNamespace

func WithNamespace(namespace string) ProviderOption

WithNamespace sets the migration namespace (usually SubApp name).

type Record

type Record struct {
	Namespace   string    `json:"namespace"`
	Connection  string    `json:"connection"`
	Version     uint64    `json:"version"`
	Name        string    `json:"name"`
	Mode        Mode      `json:"mode"`
	Scope       Scope     `json:"scope"`
	Checksum    string    `json:"checksum"`
	Status      Status    `json:"status"`
	StartedAt   time.Time `json:"startedAt,omitempty"`
	AppliedAt   time.Time `json:"appliedAt,omitempty"`
	ExecutionMS int64     `json:"executionMs,omitempty"`
	Error       string    `json:"error,omitempty"`
}

Record is a single migration execution record.

func (Record) Identity

func (r Record) Identity() string

Identity returns the stable identity key for a record.

type RegisteredMigration

type RegisteredMigration struct {
	Migration Migration
	Checksum  string
}

RegisteredMigration pairs a Migration with its source checksum.

type Registry

type Registry struct {
	Namespace  string
	Migrations []RegisteredMigration
}

Registry holds validated migrations for one namespace.

func NewRegistry

func NewRegistry(namespace string, migrations []Migration, checksums map[string]string) (*Registry, error)

NewRegistry validates and sorts migrations.

func (*Registry) Find

func (r *Registry) Find(identity string) (RegisteredMigration, bool)

Find returns a registered migration by identity.

func (*Registry) Repeatable

func (r *Registry) Repeatable() []RegisteredMigration

Repeatable returns sorted repeatable migrations.

func (*Registry) String

func (r *Registry) String() string

String implements fmt.Stringer.

func (*Registry) Versioned

func (r *Registry) Versioned() []RegisteredMigration

Versioned returns sorted versioned migrations.

type ReversibleMigration

type ReversibleMigration interface {
	Migration
	Down(ctx context.Context, db *gorm.DB) error
}

ReversibleMigration optionally supports manual Down.

type Runner

type Runner struct {
	Namespace   string
	Connection  string
	Registry    *Registry
	DB          *gorm.DB
	Store       StateStore
	Locker      Locker
	Logger      log.Logger
	Options     Options
	Fingerprint string
}

Runner executes migrations for one namespace.

func (*Runner) Plan

func (r *Runner) Plan(ctx context.Context) (Plan, error)

Plan returns the executable plan.

func (*Runner) Status

func (r *Runner) Status(ctx context.Context) (Plan, error)

Status builds the current plan without mutating state.

func (*Runner) Target

func (r *Runner) Target() TargetKey

Target returns the target key for this runner.

func (*Runner) Up

func (r *Runner) Up(ctx context.Context) error

Up applies pending and changed repeatable migrations.

func (*Runner) Validate

func (r *Runner) Validate(ctx context.Context) error

Validate checks dirty/mismatch and optionally pending without applying.

type Scope

type Scope string

Scope is used for display, filtering and operational policy.

const (
	ScopeSchema Scope = "schema"
	ScopeData   Scope = "data"
	ScopeSeed   Scope = "seed"
)

type ServiceProvider

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

ServiceProvider wires the migration runner into Harbor DI.

func NewServiceProvider

func NewServiceProvider(opts ...ProviderOption) *ServiceProvider

NewServiceProvider creates a migration provider.

func (*ServiceProvider) Boot

func (p *ServiceProvider) Boot(ctx context.Context) error

Boot runs startup migration only in web mode.

func (*ServiceProvider) Conf

func (p *ServiceProvider) Conf() map[string]string

Conf publishes default migration.yaml.

func (*ServiceProvider) Description

func (p *ServiceProvider) Description() string

Description implements ServiceProvider.

func (*ServiceProvider) Register

func (p *ServiceProvider) Register(ctx context.Context) error

Register builds and registers the Runner.

func (*ServiceProvider) SetApplication

func (p *ServiceProvider) SetApplication(app foundation.Application)

SetApplication implements ApplicationAware.

type Snapshot

type Snapshot struct {
	Namespace         string   `json:"namespace"`
	Connection        string   `json:"connection"`
	TargetFingerprint string   `json:"targetFingerprint"`
	Records           []Record `json:"records"`
}

Snapshot is the full state for one target.

func (Snapshot) IsDirty

func (s Snapshot) IsDirty() bool

IsDirty reports whether any record is running or failed.

func (Snapshot) RecordByIdentity

func (s Snapshot) RecordByIdentity(identity string) (Record, bool)

RecordByIdentity returns a record matching identity, if any.

type StartupMode

type StartupMode string

StartupMode controls boot-time migration behavior.

const (
	StartupOff      StartupMode = "off"
	StartupValidate StartupMode = "validate"
	StartupUp       StartupMode = "up"
)

type StateOptions

type StateOptions struct {
	Driver string `json:"driver"`
	Path   string `json:"path"`
}

StateOptions configures the state store.

type StateStore

type StateStore interface {
	Load(ctx context.Context, key TargetKey) (Snapshot, error)
	MarkRunning(ctx context.Context, key TargetKey, record Record) error
	MarkApplied(ctx context.Context, key TargetKey, record Record) error
	MarkFailed(ctx context.Context, key TargetKey, record Record, cause error) error
}

StateStore persists migration execution state.

type Status

type Status string

Status records execution state of a migration.

const (
	StatusRunning Status = "running"
	StatusApplied Status = "applied"
	StatusFailed  Status = "failed"
)

type TargetKey

type TargetKey struct {
	Namespace         string
	Connection        string
	TargetFingerprint string
}

TargetKey identifies a namespace + connection + target fingerprint.

type TransactionAware

type TransactionAware interface {
	TransactionMode() TransactionMode
}

TransactionAware allows a migration to override transaction policy.

type TransactionMode

type TransactionMode string

TransactionMode controls per-migration or global transaction behavior.

const (
	TransactionAuto   TransactionMode = "auto"
	TransactionAlways TransactionMode = "always"
	TransactionNever  TransactionMode = "never"
)

Source Files

  • commands.go
  • config.go
  • errors.go
  • fingerprint.go
  • lock_file.go
  • migration.go
  • planner.go
  • registry.go
  • runner.go
  • service_provider.go
  • state_file.go
  • store_lock.go
  • transaction.go

Jump to

Keyboard shortcuts

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