migris

package module
v0.4.2 Latest Latest
Warning

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

Go to latest
Published: May 23, 2026 License: MIT Imports: 18 Imported by: 3

README

Migris

Go Reference Go Report Card codecov MIT License

Migris is a database migration library for Go, inspired by Laravel's migrations. It combines the power of pressly/goose with a fluent schema builder, making migrations easy to write, run, and maintain.

Features

  • Migration management - Run up, down, reset, status, and create operations
  • Dry-run mode - Preview migrations without executing them to see generated SQL
  • Fluent schema builder - Laravel-inspired API for defining database schemas
  • Multi-database support - Works with PostgreSQL, MySQL, MariaDB, and SQLite3
  • Transaction safety - All migrations run within database transactions
  • Native Go integration - No external CLI tools required

Installation

go get -u github.com/akfaiz/migris

Quick Start

Creating Migrations

Define migrations using the fluent schema builder API:

package migrations

import (
    "github.com/akfaiz/migris"
    "github.com/akfaiz/migris/schema"
)

func init() {
    migris.AddMigrationContext(upCreateUsersTable, downCreateUsersTable)
}

func upCreateUsersTable(c schema.Context) error {
    return schema.Create(c, "users", func(table *schema.Blueprint) {
        table.ID()
        table.String("name")
        table.String("email").Unique()
        table.Timestamp("email_verified_at").Nullable()
        table.String("password")
        table.Timestamps()
    })
}

func downCreateUsersTable(c schema.Context) error {
    return schema.DropIfExists(c, "users")
}
Running Migrations

For a complete stdlib-only example, see examples/basic. For quick setup with a CLI framework, use the helpers below.

CLI Helpers

For simpler CLI integration, use the pre-built CLI helpers:

Using urfave/cli
package main

import (
    "context"
    "database/sql"
    "log"
    "os"

    "github.com/akfaiz/migris/extra/migriscli"
    _ "github.com/jackc/pgx/v5/stdlib"
)

func main() {
    db, err := sql.Open("pgx", os.Getenv("DATABASE_URL"))
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    cfg := migriscli.Config{
        DB:            db,
        Dialect:       "pgx",
        MigrationsDir: "./migrations",
        AllowMissing:  false, // set true to allow out-of-order migrations
    }

    cmd := migriscli.NewCLI(cfg)
    if err := cmd.Run(context.Background(), os.Args); err != nil {
        log.Fatal(err)
    }
}
Using Cobra
package main

import (
    "database/sql"
    "log"
    "os"

    "github.com/akfaiz/migris/extra/migriscobra"
    _ "github.com/jackc/pgx/v5/stdlib"
)

func main() {
    db, err := sql.Open("pgx", os.Getenv("DATABASE_URL"))
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    cfg := migriscobra.Config{
        DB:            db,
        Dialect:       "pgx",
        MigrationsDir: "./migrations",
        AllowMissing:  false, // set true to allow out-of-order migrations
    }

    cmd := migriscobra.NewCLI(cfg)
    if err := cmd.Execute(); err != nil {
        log.Fatal(err)
    }
}

Both CLI helpers support all migration commands: create, up, up-to, down, down-to, reset, status. The --dry-run flag is available per-command. AllowMissing in Config applies to all run operations.

Schema Builder API

The schema builder provides a fluent interface for defining database schemas:

// Creating tables
schema.Create(c, "posts", func(table *schema.Blueprint) {
    table.ID()
    table.String("title")
    table.Text("content")
    table.UnsignedBigInteger("user_id")
    table.Boolean("published").Default(false)
    table.Timestamps()

    // Foreign key constraints
    table.Foreign("user_id").References("id").On("users")

    // Indexes
    table.Index([]string{"title", "published"})
})

// Modifying existing tables
schema.Table(c, "posts", func(table *schema.Blueprint) {
    table.String("slug")
    table.DropColumn("old_column")
})

Options

Migris uses two distinct option types:

MigrisOption — constructor options

Passed to New() to configure the migrator instance:

m, err := migris.New("pgx",
    migris.WithDB(db),
    migris.WithMigrationDir("./migrations"),
    migris.WithTableName("schema_migrations"),
    migris.WithRegistry(registry),
)
Option Description
WithDB(db) Existing *sql.DB connection (caller manages lifecycle)
WithDSN(dsn) Open a new connection from DSN string (migrator manages lifecycle, call Close())
WithMigrationDir(dir) Directory for SQL migration files (default: "migrations")
WithTableName(name) Migrations tracking table name (default: "schema_migrations")
WithRegistry(r) Use an isolated migration registry instead of the global one

WithDB and WithDSN are mutually exclusive; WithDB takes precedence if both are set.

When using WithDSN, the migrator opens the connection internally and owns it. Call Close() when done:

m, err := migris.New("pgx",
    migris.WithDSN("postgres://user:pass@localhost:5432/mydb"),
    migris.WithMigrationDir("./migrations"),
)
if err != nil {
    log.Fatal(err)
}
defer m.Close()

if err := m.Up(); err != nil {
    log.Fatal(err)
}

When using WithDB, the caller owns the connection lifecycle:

db, err := sql.Open("pgx", os.Getenv("DATABASE_URL"))
if err != nil {
    log.Fatal(err)
}
defer db.Close()

m, err := migris.New("pgx",
    migris.WithDB(db),
    migris.WithMigrationDir("./migrations"),
)
Option — run-time options

Passed per-operation to control execution behaviour:

// Dry-run: print SQL without applying changes
migrator.Up(migris.WithDryRun(true))
migrator.Down(migris.WithDryRun(true))
migrator.Reset(migris.WithDryRun(true))

// Allow out-of-order migrations
migrator.Up(migris.WithAllowMissing(true))

// Combine options
migrator.UpTo(20250101000005, migris.WithDryRun(true), migris.WithAllowMissing(true))
Option Description
WithDryRun(bool) Preview SQL without executing
WithAllowMissing(bool) Apply out-of-order migrations instead of failing

All operation methods accept run-time options:

migrator.Up(opts...)
migrator.UpTo(version, opts...)
migrator.Down(opts...)
migrator.DownTo(version, opts...)
migrator.Reset(opts...)

// Context variants
migrator.UpContext(ctx, opts...)
migrator.UpToContext(ctx, version, opts...)
migrator.DownContext(ctx, opts...)
migrator.DownToContext(ctx, version, opts...)
migrator.ResetContext(ctx, opts...)

// No run-time options
migrator.Status()
migrator.Create(name)
Dry-Run Mode

Preview migrations without executing them:

// In code
if err := migrator.Up(migris.WithDryRun(true)); err != nil {
    log.Fatal(err)
}

Dry-run mode shows:

  • Which migrations would be executed
  • The exact SQL statements that would be generated
  • Execution timing and summary statistics
  • Clear indication that no database changes are made

Database Support

Currently supported databases:

  • PostgreSQL (via pgx driver)
  • MySQL
  • MariaDB
  • SQLite3

Contributing

Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.

License

Released under the MIT License. See LICENSE for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddMigrationContext

func AddMigrationContext(up, down MigrationContext)

AddMigrationContext adds Go migrations to the default registry.

func AddNamedMigrationContext

func AddNamedMigrationContext(source string, up, down MigrationContext)

AddNamedMigrationContext adds named Go migrations to the default registry.

func Create

func Create(dir, name string) error

Create creates a new migration file with the given name in the specified directory.

func ResetRegisteredMigrations added in v0.4.1

func ResetRegisteredMigrations()

ResetRegisteredMigrations clears the default global registry of migrations. This is primarily intended for tests to avoid cross-test interference.

Types

type Migrate

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

Migrate handles database migrations.

func New

func New(dialectValue string, opts ...MigrisOption) (*Migrate, error)

New creates a new Migrate instance.

func (*Migrate) Close added in v0.4.2

func (m *Migrate) Close() error

Close closes the database connection if it was opened by the migrator via WithDSN. If the connection was provided externally via WithDB, this is a no-op.

func (*Migrate) Create

func (m *Migrate) Create(name string) error

Create creates a new migration file with the given name in the specified directory.

func (*Migrate) Down

func (m *Migrate) Down(opts ...Option) error

Down rolls back the last migration.

func (*Migrate) DownContext

func (m *Migrate) DownContext(ctx context.Context, opts ...Option) error

DownContext rolls back the last migration.

func (*Migrate) DownTo

func (m *Migrate) DownTo(version int64, opts ...Option) error

DownTo rolls back the migrations to the specified version.

func (*Migrate) DownToContext

func (m *Migrate) DownToContext(ctx context.Context, version int64, opts ...Option) error

DownToContext rolls back the migrations to the specified version.

func (*Migrate) Reset

func (m *Migrate) Reset(opts ...Option) error

Reset rolls back all migrations.

func (*Migrate) ResetContext

func (m *Migrate) ResetContext(ctx context.Context, opts ...Option) error

ResetContext rolls back all migrations.

func (*Migrate) Status

func (m *Migrate) Status() error

Status returns the status of the migrations.

func (*Migrate) StatusContext

func (m *Migrate) StatusContext(ctx context.Context) error

StatusContext returns the status of the migrations.

func (*Migrate) Up

func (m *Migrate) Up(opts ...Option) error

Up applies the migrations in the specified directory.

func (*Migrate) UpContext

func (m *Migrate) UpContext(ctx context.Context, opts ...Option) error

UpContext applies the migrations in the specified directory.

func (*Migrate) UpTo

func (m *Migrate) UpTo(version int64, opts ...Option) error

UpTo applies the migrations up to the specified version.

func (*Migrate) UpToContext

func (m *Migrate) UpToContext(ctx context.Context, version int64, opts ...Option) error

UpToContext applies the migrations up to the specified version.

type Migration

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

type MigrationContext

type MigrationContext func(ctx schema.Context) error

MigrationContext is a Go migration func that is run within a transaction and receives a context.

type MigrisOption added in v0.4.2

type MigrisOption func(*Migrate)

MigrisOption configures a Migrate instance at construction time.

func WithDB

func WithDB(db *sql.DB) MigrisOption

WithDB sets the database connection for the migration.

func WithDSN added in v0.4.2

func WithDSN(dsn string) MigrisOption

WithDSN opens a database connection from the given DSN string. The migrator takes ownership of the connection; call Close when done.

func WithMigrationDir

func WithMigrationDir(dir string) MigrisOption

WithMigrationDir sets the directory for the migration files.

func WithRegistry added in v0.4.1

func WithRegistry(registry *Registry) MigrisOption

WithRegistry sets the migration registry for the migrator.

func WithTableName

func WithTableName(name string) MigrisOption

WithTableName sets the table name for the migration.

type Option

type Option func(*runOptions)

Option configures a single run operation (Up, Down, Reset, etc.).

func WithAllowMissing added in v0.4.2

func WithAllowMissing(enabled bool) Option

WithAllowMissing allows out-of-order migrations to be applied.

func WithDryRun added in v0.4.0

func WithDryRun(enabled bool) Option

WithDryRun simulates the migration without applying changes.

type Registry added in v0.4.1

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

func NewRegistry added in v0.4.1

func NewRegistry() *Registry

NewRegistry creates an isolated migration registry.

func (*Registry) AddMigrationContext added in v0.4.1

func (r *Registry) AddMigrationContext(up, down MigrationContext)

AddMigrationContext adds Go migrations to the registry.

func (*Registry) AddNamedMigrationContext added in v0.4.1

func (r *Registry) AddNamedMigrationContext(source string, up, down MigrationContext) error

AddNamedMigrationContext adds named Go migrations to the registry.

Directories

Path Synopsis
examples
basic module
extra
migriscli module
internal

Jump to

Keyboard shortcuts

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