migrator

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Sep 20, 2025 License: MIT Imports: 11 Imported by: 0

README

migrator

Simple, flexible DB migration runner with pluggable sources (dir, file, vars), SQL and hook steps, history tracking (SQLite/MySQL), and optional transactions.

Install

import "github.com/aatuh/migrator"

Quick start

// Define sources (from a dir of sql files like 001_init_up.sql, 001_init_down.sql)
src := migrator.NewDirMigrationSource("./migrations")

m := migrator.NewMigrator(db, "schema_migrations", nil /* SQLite by default */, "app").
  WithSources([]migrator.MigrationSource{src}).
  WithTransactional(true)

if err := m.MigrateUp(ctx, ""); err != nil { /* handle */ }
File/var sources
f := migrator.NewFileMigrationSource("./001_init.sql")
v := migrator.NewVarMigrationSource("002", "add_users", "CREATE TABLE users(...)", "DROP TABLE users")
Hooks
pre := func(ctx context.Context, exec migrator.Executor, path string) error { return nil }
post := func(ctx context.Context, exec migrator.Executor, path string) error { return nil }

src = src.WithFilenameParser(nil).WithAllowedExts([]string{".sql"})
src.ResolveHooks = func(filename string) (migrator.FileHookFn, migrator.FileHookFn) { return pre, post }

Notes

  • Filenames parsed as VERSION_name_up.sql / VERSION_name_down.sql by default.
  • Versions are sorted numerically; ensure zero‑padded numbers if needed.
  • History managers: SQLite (default) and MySQL; provide your own by implementing HistoryManager.
  • MigrateUp(target)/MigrateDown(target) stop at a version when set; empty target applies/rolls back all.

Documentation

Overview

Package migrator provides a simple, flexible DB migration runner with pluggable sources (dir, file, vars), SQL and hook steps, history tracking (SQLite/MySQL), and optional transactions.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type DirMigrationSource

type DirMigrationSource struct {
	Dir string
	// Optional filename parser, defaults to defaultParseFilename.
	FilenameParser ParseFilenameFn
	// Optional allowed extensions, defaults to .sql and .sqlite files.
	AllowedExts []string
	// Optional ResolveHooks returns hook functions for the given filename.
	ResolveHooks func(filename string) (preHook FileHookFn, postHook FileHookFn)
}

DirMigrationSource loads migrations from a directory. It supports optional hooks that can be explicitly tied to filenames.

func NewDirMigrationSource

func NewDirMigrationSource(dir string) *DirMigrationSource

NewDirMigrationSource creates a new DirMigrationSource for the given directory. The default parser and allowed extensions are used.

Parameters:

  • dir: The directory to load migrations from.

Returns:

  • *DirMigrationSource: A new DirMigrationSource instance.

func (*DirMigrationSource) LoadMigrations

func (d *DirMigrationSource) LoadMigrations() ([]Migration, error)

LoadMigrations loads and merges migrations from the directory.

Returns:

  • []Migration: A slice containing the loaded migrations.
  • error: An error if loading fails.

func (*DirMigrationSource) WithAllowedExts

func (d *DirMigrationSource) WithAllowedExts(
	exts []string,
) *DirMigrationSource

WithAllowedExts returns a new DirMigrationSource with the given allowed extensions.

Parameters:

  • exts: A slice of allowed extensions.

Returns:

  • *DirMigrationSource: A new DirMigrationSource instance.

func (*DirMigrationSource) WithFilenameParser

func (d *DirMigrationSource) WithFilenameParser(
	parser ParseFilenameFn,
) *DirMigrationSource

WithFilenameParser returns a new DirMigrationSource with the given parser.

Parameters:

  • parser: The ParseFilenameFn to use.

Returns:

  • *DirMigrationSource: A new DirMigrationSource instance.

type Executor

type Executor interface {
	ExecContext(
		ctx context.Context, query string, args ...any,
	) (sql.Result, error)
}

Executor is an interface that both *sql.DB and *sql.Tx implement.

type FileHookFn

type FileHookFn func(ctx context.Context, exec Executor, filePath string) error

FileHookFn is a hook function that accepts a file path.

type FileMigrationSource

type FileMigrationSource struct {
	FilePath string
	// Optional filename parser, defaults to defaultParseFilename
	FilenameParser ParseFilenameFn
	// Optional pre-hook.
	PreHook FileHookFn
	// Optional post-hook.
	PostHook FileHookFn
}

FileMigrationSource loads a single migration file and supports optional hooks.

func NewFileMigrationSource

func NewFileMigrationSource(filePath string) *FileMigrationSource

NewFileMigrationSource returns a new FileMigrationSource.

Returns:

  • *FileMigrationSource: A new FileMigrationSource instance.

func (*FileMigrationSource) LoadMigrations

func (f *FileMigrationSource) LoadMigrations() ([]Migration, error)

LoadMigrations loads the migration from the file.

Returns:

  • []Migration: A slice containing the loaded migration.
  • error: An error if loading fails.

func (*FileMigrationSource) WithFilenameParser

func (f *FileMigrationSource) WithFilenameParser(
	parser ParseFilenameFn,
) *FileMigrationSource

WithFilenameParser returns a new FileMigrationSource with the given parser.

Parameters:

  • parser: The ParseFilenameFn to use.

Returns:

  • *FileMigrationSource: A new FileMigrationSource instance.

func (*FileMigrationSource) WithPostHook

func (f *FileMigrationSource) WithPostHook(
	postHook FileHookFn,
) *FileMigrationSource

WithPostHook returns a new FileMigrationSource with the given post-hook.

Parameters:

  • postHook: The post-hook to use.

Returns:

  • *FileMigrationSource: A new FileMigrationSource with the given post-hook.

func (*FileMigrationSource) WithPreHook

func (f *FileMigrationSource) WithPreHook(
	preHook FileHookFn,
) *FileMigrationSource

WithPreHook returns a new FileMigrationSource with the given pre-hook.

Parameters:

  • preHook: The pre-hook to use.

Returns:

  • *FileMigrationSource: A new FileMigrationSource with the given pre-hook.

type HistoryManager

type HistoryManager interface {
	// EnsureHistoryTable creates the history table if it does not exist.
	EnsureHistoryTable(ctx context.Context, db *sql.DB, tableName string) error
	// RecordMigration inserts a record for the applied migration.
	RecordMigration(
		ctx context.Context,
		exec Executor,
		tableName string,
		mig Migration,
		migrationName string,
	) error
	// RemoveMigration deletes the record for the given migration.
	RemoveMigration(
		ctx context.Context,
		exec Executor,
		tableName string,
		mig Migration,
		migrationName string,
	) error
	// AppliedMigrations retrieves applied migrations as a map.
	AppliedMigrations(
		ctx context.Context, db *sql.DB, tableName string, migrationName string,
	) (map[string]bool, error)
}

HistoryManager defines methods to manage migration history.

type HookFn

type HookFn func(ctx context.Context, exec Executor) error

HookFn is a generic hook function.

type HookMigrationStep

type HookMigrationStep struct {
	UpHook   HookFn
	DownHook HookFn
}

HookMigrationStep executes custom hook functions.

func NewHookMigrationStep

func NewHookMigrationStep() *HookMigrationStep

NewHookMigrationStep returns a new HookMigrationStep with the given hooks.

Returns:

  • *MigrationStep: A new migration step.

func (HookMigrationStep) ExecuteDown

func (h HookMigrationStep) ExecuteDown(
	ctx context.Context, exec Executor,
) error

ExecuteDown executes the custom down hook.

Parameters:

  • ctx: Context to use. -exectx: The database connection.

Returns:

  • error: An error if the hook execution fails.

func (HookMigrationStep) ExecuteUp

func (h HookMigrationStep) ExecuteUp(ctx context.Context, exec Executor) error

ExecuteUp executes the custom up hook.

Parameters:

  • ctx: Context to use.
  • exec: The database connection.

Returns:

  • error: An error if the hook execution fails.

func (*HookMigrationStep) WithDownHook

func (h *HookMigrationStep) WithDownHook(downHook HookFn) MigrationStep

WithDownHook returns a new HookMigrationStep with the given down hook.

Parameters:

  • downHook: The down hook to use.

Returns:

  • MigrationStep: A new migration step.

func (*HookMigrationStep) WithUpHook

func (h *HookMigrationStep) WithUpHook(upHook HookFn) MigrationStep

WithUpHook returns a new HookMigrationStep with the given up hook.

Parameters:

  • upHook: The up hook to use.

Returns:

  • MigrationStep: A new migration step.

type Migration

type Migration struct {
	Version   string // Name is usually derived from the filename.
	Name      string
	UpSteps   []MigrationStep
	DownSteps []MigrationStep
}

Migration holds a migration's version, name, and its up and down steps.

func NewMigration

func NewMigration(
	version string,
	name string,
) *Migration

NewMigration returns a new migration.

Parameters:

  • version: The version of the migration.
  • name: The name of the migration.
  • migrationName: The name of the migration.

Returns:

  • *Migration: A new migration.

func (*Migration) WithDownSteps

func (m *Migration) WithDownSteps(downSteps []MigrationStep) *Migration

WithDownSteps returns a new Migration with the given down steps.

Parameters:

  • downSteps: The down steps to use.

Returns:

  • *Migration: A new migration.

func (*Migration) WithName

func (m *Migration) WithName(name string) *Migration

WithName returns a new Migration with the given name.

Parameters:

  • name: The name of the migration.

Returns:

  • *Migration: A new migration.

func (*Migration) WithUpSteps

func (m *Migration) WithUpSteps(upSteps []MigrationStep) *Migration

WithUpSteps returns a new Migration with the given up steps.

Parameters:

  • upSteps: The up steps to use.

Returns:

  • *Migration: A new migration.

func (*Migration) WithVersion

func (m *Migration) WithVersion(version string) *Migration

WithVersion returns a new Migration with the given version.

Parameters:

  • version: The version of the migration.

Returns:

  • *Migration: A new migration.

type MigrationSource

type MigrationSource interface {
	LoadMigrations() ([]Migration, error)
}

MigrationSource defines the interface to load migrations.

type MigrationStep

type MigrationStep interface {
	ExecuteUp(ctx context.Context, exec Executor) error
	ExecuteDown(ctx context.Context, exec Executor) error
}

MigrationStep defines a step that can be executed in up/down mode.

type Migrator

type Migrator struct {
	Sources        []MigrationSource
	DB             *sql.DB
	HistoryTable   string
	HistoryManager HistoryManager
	MigrationName  string
	Transactional  bool
}

Migrator holds migrations from one or more sources and manages history.

func NewMigrator

func NewMigrator(
	db *sql.DB,
	historyTable string,
	historyManager HistoryManager,
	migrationName string,
) *Migrator

NewMigrator returns a new Migrator instance. If historyManager is nil, it defaults to SQLiteHistoryManager.

Parameters:

  • db: A connection to the target database.
  • historyTable: The name of the table used to record applied migrations.
  • historyManager: Optional HistoryManager. Defaults to SQLiteHistoryManager.
  • migrationName: The name of the migration. It is used to distinguish migrations between multiple systems.

Returns:

  • A pointer to a Migrator.

func (*Migrator) LoadAllMigrations

func (m *Migrator) LoadAllMigrations() ([]Migration, error)

LoadAllMigrations loads and merges migrations from all sources and validates that each migration has at least one up step.

Returns:

  • A slice of loaded migrations.
  • An error if any migration is missing up steps or loading fails.

func (*Migrator) MigrateDown

func (m *Migrator) MigrateDown(ctx context.Context, target string) error

MigrateDown rolls back applied migrations down to a target version. If target is empty, all applied migrations are rolled back.

Parameters:

  • ctx: Context to use for database operations.
  • target: The migration version at which to stop rolling back (empty means rollback all).

Returns:

  • An error if any rollback step fails.

func (*Migrator) MigrateUp

func (m *Migrator) MigrateUp(ctx context.Context, target string) error

MigrateUp applies pending migrations up to a target version. If target is empty, all pending migrations are applied.

Parameters:

  • ctx: Context to use for database operations.
  • target: The target migration version to stop at (empty means all).

Returns:

  • An error if any migration fails.

func (*Migrator) WithDB

func (m *Migrator) WithDB(db *sql.DB) *Migrator

WithDB returns a new Migrator with the given database connection.

Parameters:

  • db: A database connection.

Returns:

  • *Migrator: A new Migrator instance.

func (*Migrator) WithHistoryManager

func (m *Migrator) WithHistoryManager(historyManager HistoryManager) *Migrator

WithHistoryManager returns a new Migrator with the given HistoryManager.

Parameters:

  • historyManager: A HistoryManager instance.

Returns:

  • *Migrator: A new Migrator instance.

func (*Migrator) WithHistoryTable

func (m *Migrator) WithHistoryTable(historyTable string) *Migrator

WithHistoryTable returns a new Migrator with the given history table name.

Parameters:

  • historyTable: The name of the history table.

Returns:

  • *Migrator: A new Migrator instance.

func (*Migrator) WithMigrationName

func (m *Migrator) WithMigrationName(migrationName string) *Migrator

WithMigrationName returns a new Migrator with the given migration name.

Parameters:

  • migrationName: The name of the migration.

Returns:

  • *Migrator: A new Migrator instance.

func (*Migrator) WithSources

func (m *Migrator) WithSources(sources []MigrationSource) *Migrator

WithSources returns a new Migrator with the given sources.

Parameters:

  • sources: A slice of MigrationSource instances.

Returns:

  • *Migrator: A new Migrator instance.

func (*Migrator) WithTransactional

func (m *Migrator) WithTransactional(transactional bool) *Migrator

WithTransactional returns a new Migrator with the transactional flag set.

Parameters:

  • transactional: Whether to use transactions.

Returns:

  • *Migrator: A new Migrator instance.

type MySQLHistoryManager

type MySQLHistoryManager struct{}

MySQLHistoryManager implements HistoryManager for MySQL.

func NewMySQLHistoryManager

func NewMySQLHistoryManager() *MySQLHistoryManager

NewMySQLHistoryManager returns a new MySQLHistoryManager.

Returns:

  • *MySQLHistoryManager: A new MySQLHistoryManager instance.

func (MySQLHistoryManager) AppliedMigrations

func (m MySQLHistoryManager) AppliedMigrations(
	ctx context.Context, db *sql.DB, tableName string, migrationName string,
) (map[string]bool, error)

AppliedMigrations retrieves applied migrations from MySQL.

Parameters:

  • ctx: Context to use.
  • db: The database connection.
  • tableName: The name of the history table.
  • migrationName: The name of the migration.

Returns:

  • map[string]bool: A map of applied migrations.
  • error: An error if the query fails.

func (MySQLHistoryManager) EnsureHistoryTable

func (m MySQLHistoryManager) EnsureHistoryTable(
	ctx context.Context, db *sql.DB, tableName string,
) error

EnsureHistoryTable creates the history table in MySQL.

Parameters:

  • ctx: Context to use.
  • db: The database connection.
  • tableName: The name of the history table.

Returns:

  • error: An error if the table creation fails.

func (MySQLHistoryManager) RecordMigration

func (m MySQLHistoryManager) RecordMigration(
	ctx context.Context,
	exec Executor,
	tableName string,
	mig Migration,
	migrationName string,
) error

RecordMigration inserts an applied migration record in MySQL.

Parameters:

  • ctx: Context to use.
  • exec: The executor to use.
  • tableName: The name of the history table.
  • mig: The migration to record.
  • migrationName: The name of the migration.

Returns:

  • error: An error if the record insertion fails.

func (MySQLHistoryManager) RemoveMigration

func (m MySQLHistoryManager) RemoveMigration(
	ctx context.Context,
	exec Executor,
	tableName string,
	mig Migration,
	migrationName string,
) error

RemoveMigration deletes the migration record in MySQL.

Parameters:

  • ctx: Context to use.
  • exec: The executor to use.
  • tableName: The name of the history table.
  • mig: The migration to remove.
  • migrationName: The name of the migration.

Returns:

  • error: An error if the record deletion fails.

type ParseFilenameFn

type ParseFilenameFn func(filename string) (
	version string, name string, direction string, ok bool,
)

ParseFilenameFn defines a function to extract migration details from a file name. It returns the version, name, direction ("up" or "down"), and a boolean indicating if parsing succeeded.

type SQLMigrationStep

type SQLMigrationStep struct {
	SQL string
}

SQLMigrationStep executes a plain SQL statement.

func NewSQLMigrationStep

func NewSQLMigrationStep(sql string) *SQLMigrationStep

NewSQLMigrationStep returns a new SQLMigrationStep.

Parameters:

  • sql: The SQL statement to execute.

Returns:

  • *SQLMigrationStep: A new SQLMigrationStep.

func (SQLMigrationStep) ExecuteDown

func (s SQLMigrationStep) ExecuteDown(
	ctx context.Context, exec Executor,
) error

ExecuteDown executes the SQL query for downward migration.

Parameters:

  • ctx: Context to use.
  • exec: The database connection.

Returns:

  • error: An error if the query execution fails.

func (SQLMigrationStep) ExecuteUp

func (s SQLMigrationStep) ExecuteUp(ctx context.Context, exec Executor) error

ExecuteUp executes the SQL query for upward migration.

Parameters:

  • ctx: Context to use.
  • exec: The database connection.

Returns:

  • error: An error if the query execution fails.

func (*SQLMigrationStep) WithSQL

func (s *SQLMigrationStep) WithSQL(sql string) *SQLMigrationStep

WithSQL returns a new SQLMigrationStep with the given SQL statement.

Parameters:

  • sql: The SQL statement to execute.

Returns:

  • *SQLMigrationStep: A new SQLMigrationStep.

type SQLiteHistoryManager

type SQLiteHistoryManager struct{}

SQLiteHistoryManager implements HistoryManager for SQLite.

func NewSQLiteHistoryManager

func NewSQLiteHistoryManager() *SQLiteHistoryManager

NewSQLiteHistoryManager returns a new SQLiteHistoryManager.

Returns:

  • *SQLiteHistoryManager: A new SQLiteHistoryManager instance.

func (SQLiteHistoryManager) AppliedMigrations

func (s SQLiteHistoryManager) AppliedMigrations(
	ctx context.Context, db *sql.DB, tableName string, migrationName string,
) (map[string]bool, error)

AppliedMigrations retrieves applied migrations from SQLite.

Parameters:

  • ctx: Context to use.
  • db: The database connection.
  • tableName: The name of the history table.
  • migrationName: The name of the migration.

Returns:

  • map[string]bool: A map of applied migrations.
  • error: An error if the query fails.

func (SQLiteHistoryManager) EnsureHistoryTable

func (s SQLiteHistoryManager) EnsureHistoryTable(
	ctx context.Context, db *sql.DB, tableName string,
) error

EnsureHistoryTable creates the history table in SQLite.

Parameters:

  • ctx: Context to use.
  • db: The database connection.
  • tableName: The name of the history table.

Returns:

  • error: An error if the table creation fails.

func (SQLiteHistoryManager) RecordMigration

func (s SQLiteHistoryManager) RecordMigration(
	ctx context.Context,
	exec Executor,
	tableName string,
	mig Migration,
	migrationName string,
) error

RecordMigration inserts an applied migration record in SQLite.

Parameters:

  • ctx: Context to use.
  • exec: The executor to use.
  • tableName: The name of the history table.
  • mig: The migration to record.

Returns:

  • error: An error if the record insertion fails.

func (SQLiteHistoryManager) RemoveMigration

func (s SQLiteHistoryManager) RemoveMigration(
	ctx context.Context,
	exec Executor,
	tableName string,
	mig Migration,
	migrationName string,
) error

RemoveMigration deletes the migration record in SQLite.

Parameters:

  • ctx: Context to use.
  • exec: The executor to use.
  • tableName: The name of the history table.
  • mig: The migration to remove.
  • migrationName: The name of the migration.

Returns:

  • error: An error if the record deletion fails.

type VarMigrationSource

type VarMigrationSource struct {
	Version string
	Name    string
	UpSQL   string
	DownSQL string
}

VarMigrationSource uses SQL queries defined in variables.

func NewVarMigrationSource

func NewVarMigrationSource(
	version string, name string, upSQL string, downSQL string,
) *VarMigrationSource

NewVarMigrationSource creates a new VarMigrationSource.

Parameters:

  • version: The version of the migration.
  • name: The name of the migration.
  • upSQL: The SQL to execute when applying the migration.
  • downSQL: The SQL to execute when removing the migration.

Returns:

  • *VarMigrationSource: A new VarMigrationSource.

func (*VarMigrationSource) LoadMigrations

func (v *VarMigrationSource) LoadMigrations() ([]Migration, error)

LoadMigrations loads the variable-defined migration.

Returns:

  • []Migration: A slice containing the loaded migration.
  • error: An error if loading fails.

Jump to

Keyboard shortcuts

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