Documentation
¶
Overview ¶
Package migrate provides a database migration framework with support for versioned migrations, rollbacks, and migration tracking.
The package is designed to be database-agnostic and can be used as a standalone library for managing database schema changes.
Key features:
- Lexicographical migration ordering by ID
- Transactional migration execution
- Migration rollback support
- Customizable logging
- Duplicate migration detection
Basic Usage:
db, err := sql.Open("sqlite", "database.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
migrator, err := migrate.New(db, nil)
if err != nil {
log.Fatal(err)
}
if err := migrator.AddMigration(&YourMigration{}); err != nil {
log.Fatal(err)
}
if err := migrator.Up(context.Background()); err != nil {
log.Fatal(err)
}
The Up() and Down() methods accept a context.Context parameter for cancellation support. Use context.Background() for non-cancelable operations, or a context with timeout for long-running migrations.
Migration ID Format:
Migrations must have an ID in the format: YYYY_MM_DD_HHMM_description For example: 2026_03_21_1200_create_users_table
The date part must be a valid calendar date (e.g., February 30 will be rejected).
Index ¶
- Constants
- func GetBuiltinMigrationID(format NamingFormat) string
- func GetDefaultTableName() string
- func ValidateMigrationID(id string, format NamingFormat) error
- func ValidateTableName(name string) error
- type MigrationInterface
- type MigrationRecord
- type MigrationStatus
- type MigratorInterface
- type NamingFormat
- type Options
Constants ¶
const ( // DefaultTableName is the default name for the migrations tracking table // Can be overridden by setting the MIGRATE_TABLE_NAME environment variable DefaultTableName = "migration_tracker" ColumnID = "id" ColumnBatch = "batch" ColumnDescription = "description" ColumnStartedAt = "started_at" ColumnCompletedAt = "completed_at" DirectionUp = "up" DirectionDown = "down" BuiltinMigrationIDBase = "table_migration_tracker_create" // NamingFormatPrefixYYYY_MM_DD_HHMM uses timestamp-based format NamingFormatPrefixYYYY_MM_DD_HHMM NamingFormat = "YYYY_MM_DD_HHMM" // NamingFormatPrefixYYYY_MM_DD_NNN uses sequence-based format NamingFormatPrefixYYYY_MM_DD_NNN NamingFormat = "YYYY_MM_DD_NNN" // NamingFormatPrefixNone uses no prefix format restriction NamingFormatPrefixNone NamingFormat = "none" )
Variables ¶
This section is empty.
Functions ¶
func GetBuiltinMigrationID ¶ added in v0.3.0
func GetBuiltinMigrationID(format NamingFormat) string
GetBuiltinMigrationID returns the builtin migration ID based on naming format
Business Logic: - Uses date 2001-01-01 to ensure builtin migration runs first (lexicographically) - For NNN format: uses 3-digit sequence (000) - For HHMM format: uses 4-digit time (0000) - For None format: uses underscore prefix only - Defaults to HHMM format if an unknown format is provided - Ensures builtin migration is always the first in execution order
func GetDefaultTableName ¶ added in v0.3.0
func GetDefaultTableName() string
GetDefaultTableName returns the default table name, checking for environment variable override
Business Logic: - Checks for MIGRATE_TABLE_NAME environment variable first - If environment variable is set and non-empty, returns that value - Otherwise returns the DefaultTableName constant ("migration_tracker") - Allows runtime configuration without code changes
func ValidateMigrationID ¶ added in v0.3.0
func ValidateMigrationID(id string, format NamingFormat) error
ValidateMigrationID validates that the migration ID follows the specified format Supported formats:
- YYYY_MM_DD_HHMM_description (for HHMM format)
- YYYY_MM_DD_NNN_description (for NNN format)
- none (no prefix format restriction)
Business Logic: - Enforces maximum length of 255 characters - Rejects empty IDs - For "none" format: only validates length and non-empty - For other formats: requires at least 5 underscore-separated parts - Validates date part (YYYY_MM_DD) is a valid calendar date - Validates time part (HHMM) or sequence part (NNN) based on format - Validates description exists and is within length limits - Ensures lexicographical ordering by date/time
func ValidateTableName ¶ added in v0.3.0
ValidateTableName ensures the table name contains only safe characters This function is exported to allow external validation of table names before creating a migrator instance.
Business Logic: - Rejects empty table names - Enforces maximum length of 64 characters - First character must be a letter or underscore (not a digit) - All characters must be alphanumeric or underscore - Prevents SQL injection and naming conflicts
Types ¶
type MigrationInterface ¶
type MigrationInterface interface {
// ID returns the unique identifier for this migration
// Format: YYYY_MM_DD_HHMM_description (e.g., 2026_03_21_1200_create_users_table)
ID() string
// Description returns a human-readable description for the migration
// Example: "Create users table with email index"
Description() string
// Up executes the migration to apply database changes
// Takes context for cancellation support and transaction for atomic operations
Up(ctx context.Context, tx *sql.Tx) error
// Down executes the rollback to revert database changes
// Takes context for cancellation support and transaction for atomic operations
// Should undo exactly what Up() did
Down(ctx context.Context, tx *sql.Tx) error
}
MigrationInterface defines the contract that all migrations must implement
func GetBuiltinMigrations ¶
func GetBuiltinMigrations(tableName string, format NamingFormat) []MigrationInterface
GetBuiltinMigrations returns the built-in migrations with the specified naming format
Business Logic: - Returns a slice containing all built-in migrations - Currently includes only the schema migrations table creation - The table name and naming format are passed to the migration - Built-in migrations are automatically added before user migrations
func NewCreateSchemaMigrationsTable ¶
func NewCreateSchemaMigrationsTable(tableName string, format NamingFormat) MigrationInterface
NewCreateSchemaMigrationsTable creates a new builtin migration for the schema migrations table
Business Logic: - Creates a migration instance with the specified table name and naming format - The migration will create a table to track applied migrations - Table name can be customized (defaults to "migration_tracker") - Naming format determines the migration ID format
type MigrationRecord ¶ added in v0.3.0
type MigrationRecord struct {
ID string
Batch string
Description string
StartedAt string
CompletedAt string
}
MigrationRecord represents a migration record from the database
type MigrationStatus ¶ added in v0.3.0
MigrationStatus represents the status of a single migration
type MigratorInterface ¶
type MigratorInterface interface {
// AddMigration adds a new migration to the list
AddMigration(migration MigrationInterface) error
// AddMigrations adds multiple migrations to the runner
AddMigrations(migrations []MigrationInterface) error
// Up runs all pending migrations
Up(ctx context.Context) error
// Down rolls back the last migration
Down(ctx context.Context) error
// Status shows migration status (prints to stdout)
Status(ctx context.Context) error
// GetStatus returns migration status as structured data
GetStatus(ctx context.Context) ([]MigrationStatus, error)
// GetHistory returns the migration execution history from the database
GetHistory(ctx context.Context) ([]MigrationRecord, error)
}
MigratorInterface defines the contract for database migration operations
func New ¶
func New(db *sql.DB, opts *Options) (MigratorInterface, error)
New creates a new migrator instance
Business Logic: - Initializes options to empty struct if nil provided - Uses provided table name or defaults from GetDefaultTableName() - Validates table name for safety (alphanumeric and underscore only) - Uses provided logger or nil (disables logging) - Uses provided naming format or defaults to HHMM format - Returns migrator implementation with initialized migrations list
type NamingFormat ¶ added in v0.3.0
type NamingFormat string
NamingFormat defines the format for migration IDs
type Options ¶
type Options struct {
// MigrationTableName is the name of the table used to track applied migrations.
// Defaults to "migration_tracker" if not specified.
MigrationTableName string
// Logger is used for migration logging.
// If nil, logging is disabled.
Logger *slog.Logger
// NamingFormatPrefix specifies the prefix format for migration IDs.
// Use NamingFormatPrefixNone ("none") to disable prefix validation.
// Empty string ("") defaults to NamingFormatPrefixYYYY_MM_DD_HHMM.
NamingFormatPrefix NamingFormat
}
Options configures the Migrator behavior