golazy.dev golazy.dev / lazymigrate Index | Files | Directories

package lazymigrate

import "golazy.dev/lazymigrate"

Package lazymigrate loads, plans, and applies ordered file-based migrations through backend-owned execution.

The package is intentionally backend-agnostic. It knows how to collect source migrations, compare them with the migration IDs a backend reports as already applied, and build an up, down, or redo plan. The backend owns the concrete migration language, the meaning of up and down sections, locking, transactions, metadata tables, and schema load or dump support. Production backend implementations must synchronize migration application across processes so multiple app instances can start with migration mode enabled without applying the same step twice or corrupting migration metadata.

A Source returns migration files. FromFS adapts an fs.FS plus an explicit directory, skips nested directories and migrations.toml, rejects Go migration files, and requires each filename to contain a sortable timestamp. ForDatabase is the conventional app-root helper for migrations/<database>, for example migrations/postgres. File extensions are ignored for migration IDs: 202606280001_create_documents.sql becomes ID 202606280001_create_documents. Prefix and Timestamp are parsed only for stable ordering; duplicate IDs across all loaded sources are rejected.

Catalog is useful when an application combines its own migrations with package-provided migrations. PostgreSQL service packages in golazy.dev/pg, such as pgjobs, pgfiles, pgmedia, and pgstorage, expose embedded migrations as lazymigrate.Source values so an application can add them to the same catalog as application migrations.

DB and Databases describe the same source/backend relationship for lazyapp integration. Each Databases entry is one logical database with its own Backend and Source values. This keeps lazymigrate backend-agnostic while letting a conventional lazyapp bundle the migrations needed by the application binary.

A Migrator is the planner and executor. List reports applied source migrations, pending source migrations, and missing backend migrations. PlanUp, PlanDown, and PlanRedo return the Step values that would run without setting up backend metadata. Up, Down, and Redo call Backend.Setup before planning, then pass each Step to Backend.Run in order. Apply is for callers that already have a Plan; it also calls Backend.Setup before running that plan. A migration recorded by the backend but missing from the loaded sources blocks execution plans so down and redo operations do not operate from incomplete source history.

Backend implementations connect this package to a real store. The golazy.dev/pg/pgmigrate package implements Backend for PostgreSQL. It parses SQL files with -- +lazy Up and -- +lazy Down sections, stores applied IDs in lazy_migrations, runs each step and metadata update in a transaction, and uses an advisory lock while applying a migration. lazymigrate itself does not parse those sections; it passes the file content through unchanged so other backends can use their own format.

The fakemigrator subpackage provides an in-memory Backend for tests, examples, and early command wiring. It records planned steps and applied IDs but does not execute SQL.

Types

type Backend

Backend connects lazymigrate plans to a concrete store.

Production implementations must be safe for multiple application processes to call at the same time. Migration application must be synchronized by the backend so only one caller can apply a conflicting step or plan, the schema change and metadata update are committed atomically, and a concurrent caller that races with an already-applied migration does not corrupt migration state.

type Backend interface {
	Setup(context.Context) error
	List(context.Context) ([]BackendMigration, error)
	Run(context.Context, Step) error
	DumpSchema(context.Context) ([]byte, error)
	LoadSchema(context.Context, []byte) error
}

type Databases

Databases maps logical database names to independent migration backends.

type Databases map[string]DB
func (databases Databases) Get

Get returns the named database configuration.

func (databases Databases) Get(name string) (DB, bool)
func (databases Databases) Migrator

Migrator returns the named database migrator.

func (databases Databases) Migrator(name string) (*Migrator, error)
func (databases Databases) Names

Names returns configured database names in stable order.

func (databases Databases) Names() []string

type Migrator

type Migrator struct {
	// contains filtered or unexported fields
}
func New
func New(config Config) (*Migrator, error)
func (m *Migrator) Apply
func (m *Migrator) Apply(ctx context.Context, plan Plan) error
func (m *Migrator) Down
func (m *Migrator) Down(ctx context.Context, limit int) (Plan, error)
func (m *Migrator) DumpSchema
func (m *Migrator) DumpSchema(ctx context.Context) ([]byte, error)
func (m *Migrator) List
func (m *Migrator) List(ctx context.Context) ([]Status, error)
func (m *Migrator) LoadSchema
func (m *Migrator) LoadSchema(ctx context.Context, schema []byte) error
func (m *Migrator) PlanDown
func (m *Migrator) PlanDown(ctx context.Context, limit int) (Plan, error)
func (m *Migrator) PlanRedo
func (m *Migrator) PlanRedo(ctx context.Context, limit int) (Plan, error)
func (m *Migrator) PlanUp
func (m *Migrator) PlanUp(ctx context.Context, limit int) (Plan, error)
func (m *Migrator) Redo
func (m *Migrator) Redo(ctx context.Context, limit int) (Plan, error)
func (m *Migrator) Setup
func (m *Migrator) Setup(ctx context.Context) error
func (m *Migrator) Up
func (m *Migrator) Up(ctx context.Context, limit int) (Plan, error)

Directories

Path Synopsis
lazymigrate/fakemigrator Package fakemigrator provides an in-memory lazymigrate backend for tests.