migrator

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Apr 5, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrConnectionFailed     = errors.New("database connection failed")
	ErrMigrationNotFound    = errors.New("migration not found")
	ErrDuplicateMigration   = errors.New("duplicate migration name")
	ErrInvalidMigrationName = errors.New("invalid migration name")
	ErrTransactionFailed    = errors.New("transaction failed")
	ErrTrackingTable        = errors.New("migration tracking table error")
	ErrDuplicateSeeder      = errors.New("duplicate seeder name")
	ErrInvalidSeederName    = errors.New("invalid seeder name")
	ErrCircularDependency   = errors.New("circular seeder dependency")
	ErrSeederNotFound       = errors.New("seeder not found")
	ErrUnsupportedType      = errors.New("unsupported column type")
	ErrConnectionNotFound   = errors.New("connection not found")
	ErrConfigValidation     = errors.New("configuration validation failed")
)

Sentinel errors for common failure scenarios across the migration system. All errors support errors.Is() and errors.As() for inspection. Wrap these with fmt.Errorf("context: %w", ErrXxx) to preserve the error chain.

Functions

func AutoRegister

func AutoRegister(name string, m Migration)

AutoRegister registers a migration in the global auto-registry. Intended to be called from init() functions in migration files. Panics if the name is invalid or duplicate (fail-fast at startup).

func GetAutoRegistered

func GetAutoRegistered() []registeredMigration

GetAutoRegistered returns all auto-registered migrations in timestamp order.

func ResetAutoRegistry

func ResetAutoRegistry()

ResetAutoRegistry clears the global auto-registry (for testing only).

func ResolveGrammar

func ResolveGrammar(driver string) (schema.Grammar, error)

ResolveGrammar returns the schema.Grammar for the given database driver name. It returns an error if the driver is not recognized.

func Run

func Run()

Run is the all-in-one entry point for the go-migration CLI. It handles the full lifecycle: parse CLI args, load config, connect DB, auto-discover migrations and seeders, and dispatch the command. On fatal error it prints to stderr and exits with code 1.

Usage in main.go:

package main

import (
    _ "myapp/migrations"
    _ "myapp/seeders"
    "github.com/gopackx/go-migration/pkg/migrator"
)

func main() {
    migrator.Run()
}

Types

type AfterHookFunc

type AfterHookFunc func(name string, direction string, duration time.Duration) error

AfterHookFunc is a callback invoked after a migration executes. It receives the migration name, direction, and execution duration.

type BatchManager

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

BatchManager provides batch-level operations on top of the Tracker.

func NewBatchManager

func NewBatchManager(tracker *Tracker) *BatchManager

NewBatchManager creates a new BatchManager that delegates to the given Tracker.

func (*BatchManager) GetLastBatch

func (b *BatchManager) GetLastBatch() ([]MigrationRecord, error)

GetLastBatch returns all migration records from the most recent batch. Returns an empty slice if no migrations have been applied.

func (*BatchManager) GetLastNMigrations

func (b *BatchManager) GetLastNMigrations(n int) ([]MigrationRecord, error)

GetLastNMigrations returns the last N applied migrations in reverse timestamp order. If fewer than N migrations exist, all are returned.

func (*BatchManager) NextBatchNumber

func (b *BatchManager) NextBatchNumber() (int, error)

NextBatchNumber returns the next batch number to use for a new migration run. It is always one greater than the current highest batch number.

type HookFunc

type HookFunc func(name string, direction string) error

HookFunc is a callback invoked before a migration executes. It receives the migration name and direction ("up" or "down").

type HookManager

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

HookManager manages before and after migration hooks.

func NewHookManager

func NewHookManager() *HookManager

NewHookManager creates a new HookManager with empty hook slices.

func (*HookManager) RegisterAfter

func (h *HookManager) RegisterAfter(fn AfterHookFunc)

RegisterAfter adds an after-migration hook. Hooks run in registration order.

func (*HookManager) RegisterBefore

func (h *HookManager) RegisterBefore(fn HookFunc)

RegisterBefore adds a before-migration hook. Hooks run in registration order.

func (*HookManager) RunAfter

func (h *HookManager) RunAfter(name, direction string, duration time.Duration) error

RunAfter invokes all registered after hooks in order. If any hook returns an error, it is ignored and execution continues. The caller (Migration_Runner) is responsible for logging hook errors.

func (*HookManager) RunBefore

func (h *HookManager) RunBefore(name, direction string) error

RunBefore invokes all registered before hooks in order. If any hook returns an error, execution stops and the error is returned (abort).

type Logger

type Logger interface {
	Info(msg string, args ...any)
	Error(msg string, args ...any)
}

Logger defines a minimal logging interface for the runner. This will be replaced by the full logger package once implemented.

type Migration

type Migration interface {
	Up(schema *schema.Builder) error
	Down(schema *schema.Builder) error
}

Migration defines the contract for a database migration. Each migration must implement Up and Down methods that receive a schema Builder to define schema changes.

type MigrationError

type MigrationError struct {
	MigrationName string // nama migrasi yang gagal
	SQL           string // statement SQL yang menyebabkan kegagalan
	Position      string // informasi posisi dari DB (opsional)
	Cause         error  // error asli dari database driver
}

MigrationError menyimpan konteks kegagalan migrasi.

func (*MigrationError) Error

func (e *MigrationError) Error() string

func (*MigrationError) Unwrap

func (e *MigrationError) Unwrap() error

type MigrationRecord

type MigrationRecord struct {
	Name      string
	Batch     int
	CreatedAt time.Time
}

MigrationRecord represents a single row in the migration tracking table.

type MigrationStatus

type MigrationStatus struct {
	Name      string
	Applied   bool
	Batch     int
	AppliedAt *time.Time
}

MigrationStatus represents the status of a single registered migration.

type Migrator

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

func New

func New(db *sql.DB, opts ...Option) *Migrator

New creates a new Migrator with the given database connection and options. Defaults: table name "migrations", nil grammar, nil logger.

func (*Migrator) AfterMigrate

func (m *Migrator) AfterMigrate(fn AfterHookFunc)

AfterMigrate registers an after-migration hook.

func (*Migrator) AutoDiscover

func (m *Migrator) AutoDiscover() error

AutoDiscover loads all migrations from the global auto-registry into the Migrator's internal registry.

func (*Migrator) BeforeMigrate

func (m *Migrator) BeforeMigrate(fn HookFunc)

BeforeMigrate registers a before-migration hook.

func (*Migrator) Fresh

func (m *Migrator) Fresh() error

Fresh drops all tables and then runs all migrations up. Requires a grammar to be configured via WithGrammar.

func (*Migrator) Refresh

func (m *Migrator) Refresh() error

Refresh resets all migrations and then runs them all up again.

func (*Migrator) Register

func (m *Migrator) Register(name string, migration Migration) error

Register adds a migration to the registry.

func (*Migrator) Reset

func (m *Migrator) Reset() error

Reset rolls back all applied migrations in reverse order.

func (*Migrator) Rollback

func (m *Migrator) Rollback(steps int) error

Rollback rolls back migrations. If steps == 0, rolls back the last batch. If steps > 0, rolls back the last N individual migrations.

func (*Migrator) Status

func (m *Migrator) Status() ([]MigrationStatus, error)

Status returns the status of all registered migrations, indicating whether each has been applied, its batch number, and applied timestamp.

func (*Migrator) Up

func (m *Migrator) Up() error

Up runs all pending migrations in timestamp order. All migrations executed in a single Up() call share the same batch number.

type Option

type Option func(*Migrator)

Option configures a Migrator.

func WithAutoDiscover

func WithAutoDiscover() Option

WithAutoDiscover returns an Option that loads auto-registered migrations. Panics if AutoDiscover() returns an error (consistent with option pattern).

func WithDryRun

func WithDryRun(w io.Writer) Option

WithDryRun enables dry-run mode: SQL statements are written to w instead of being executed against the database.

func WithGrammar

func WithGrammar(g schema.Grammar) Option

WithGrammar sets the SQL grammar used by the Runner and Fresh().

func WithLogger

func WithLogger(l Logger) Option

WithLogger sets the logger used by the Migrator and Runner.

func WithProgress

func WithProgress(fn ProgressFunc) Option

WithProgress sets a callback that is invoked after each migration completes during Up, Rollback, or Reset operations.

func WithTableName

func WithTableName(name string) Option

WithTableName sets the migration tracking table name (default: "migrations").

type ProgressEvent

type ProgressEvent struct {
	Name      string
	Index     int // 0-based position
	Total     int // total migrations in this operation
	Duration  time.Duration
	Direction string // "up" or "down"
}

Migrator is the top-level orchestrator that wires together the Registry, Runner, Tracker, BatchManager, and HookManager to execute migration lifecycle operations. ProgressEvent describes the completion of a single migration during an Up, Rollback, or Reset operation.

type ProgressFunc

type ProgressFunc func(event ProgressEvent)

ProgressFunc is a callback invoked after each migration completes.

type Registry

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

Registry stores migrations in timestamp-sorted order.

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates an empty migration registry.

func (*Registry) Count

func (r *Registry) Count() int

Count returns the number of registered migrations.

func (*Registry) Get

func (r *Registry) Get(name string) (Migration, error)

Get retrieves a migration by name. Returns ErrMigrationNotFound if not found.

func (*Registry) GetAll

func (r *Registry) GetAll() []registeredMigration

GetAll returns all registered migrations in timestamp-sorted order.

func (*Registry) Register

func (r *Registry) Register(name string, m Migration) error

Register adds a migration with the given name to the registry. Names must match YYYYMMDDHHMMSS_description or YYYY_MM_DD_HHMMSS_RRRR_description and be unique.

type Runner

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

Runner executes migration Up/Down methods within transactions.

func NewRunner

func NewRunner(db *sql.DB, grammar schema.Grammar, logger Logger) *Runner

NewRunner creates a new Runner with the given database connection, grammar, and logger. The logger parameter may be nil, in which case logging is silently skipped.

func (*Runner) Execute

func (r *Runner) Execute(m Migration, direction string, migrationName ...string) error

Execute runs a migration in the given direction ("up" or "down"). migrationName is used to provide context in error messages via MigrationError. If dry-run mode is active, it uses a DryRunExecutor instead of the real database. If the migration implements TransactionOption and DisableTransaction() returns true, it executes without a transaction. Otherwise it delegates to ExecuteInTransaction.

func (*Runner) ExecuteDryRun

func (r *Runner) ExecuteDryRun(m Migration, direction string, migrationName string) error

ExecuteDryRun runs a migration in the given direction ("up" or "down") with a migration name prefix written to the dry-run writer.

func (*Runner) ExecuteInTransaction

func (r *Runner) ExecuteInTransaction(m Migration, direction string, migrationName ...string) error

ExecuteInTransaction runs a migration within a database transaction. On success the transaction is committed. On migration error the transaction is rolled back. If commit fails, a rollback is attempted and ErrTransactionFailed is returned. SQL errors are wrapped in MigrationError when migrationName is provided.

func (*Runner) SetDryRun

func (r *Runner) SetDryRun(w io.Writer)

SetDryRun enables dry-run mode on the Runner. When active, SQL statements are written to the given writer instead of being executed against the database.

type Tracker

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

Tracker manages the migrations tracking table in the database.

func NewTracker

func NewTracker(db *sql.DB, tableName string) *Tracker

NewTracker creates a new Tracker that uses the given database connection and stores records in the specified table.

func (*Tracker) EnsureTable

func (t *Tracker) EnsureTable() error

EnsureTable creates the migration tracking table if it does not already exist. This operation is idempotent — calling it multiple times has no effect.

func (*Tracker) GetApplied

func (t *Tracker) GetApplied() ([]MigrationRecord, error)

GetApplied returns all migration records ordered by name ascending.

func (*Tracker) GetByBatch

func (t *Tracker) GetByBatch(batch int) ([]MigrationRecord, error)

GetByBatch returns all migration records for the given batch number, ordered by name ascending.

func (*Tracker) GetLastBatchNumber

func (t *Tracker) GetLastBatchNumber() (int, error)

GetLastBatchNumber returns the highest batch number in the tracking table. Returns 0 if no records exist.

func (*Tracker) Record

func (t *Tracker) Record(name string, batch int) error

Record inserts a new migration record with the given name and batch number.

func (*Tracker) Remove

func (t *Tracker) Remove(name string) error

Remove deletes a migration record by name.

type TransactionOption

type TransactionOption interface {
	DisableTransaction() bool
}

TransactionOption allows a migration to opt out of transaction wrapping. If a migration implements this interface and DisableTransaction returns true, the runner will execute it without a surrounding database transaction.

Jump to

Keyboard shortcuts

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