miggo

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Feb 4, 2026 License: MIT Imports: 11 Imported by: 0

README

miggo

A simple, flexible SQL migration library for Go with zero dependencies on ORMs or frameworks.

Features

  • 📁 Directory-based migrations - Each migration is a folder with .up.sql and .down.sql files
  • 🔢 Sequential numbering - Automatic migration indexing with 001_, 002_, etc.
  • Transaction safety - Each migration runs in a transaction
  • 🔄 Full rollback support - Down migrations and reset functionality
  • 🎯 Insert at any position - Add migrations between existing ones with automatic renumbering
  • 🗄️ PostgreSQL ready - Works with any database/sql compatible driver
  • 🎨 Colored output - Clear visual feedback with color-coded messages

Installation

go get github.com/matheusbastani/miggo

Quick Start

package main

import (
    "database/sql"
    _ "github.com/lib/pq"
    "github.com/matheusbastani/miggo"
)

func main() {
    db, _ := sql.Open("postgres", "postgres://user:pass@localhost/dbname?sslmode=disable")
    defer db.Close()

    // Create a migrator instance
    m := miggo.New(db, "./migrations")

    // Create a new migration
    m.Create("create_users_table")

    // Apply all pending migrations
    m.Up()

    // Check current version
    m.Version()
}

Migration Structure

Migrations are organized in numbered directories:

migrations/
├── 001_create_users/
│   ├── 20240204120000_create_users.up.sql
│   └── 20240204120000_create_users.down.sql
├── 002_add_posts/
│   ├── 20240204130000_add_posts.up.sql
│   └── 20240204130000_add_posts.down.sql
└── 003_add_comments/
    ├── 20240204140000_add_comments.up.sql
    └── 20240204140000_add_comments.down.sql
Methods
Up()
m.Up()

Applies all pending migrations in sequential order. Creates the migrations tracking table if it doesn't exist.

Down()
m.Down()

Rolls back the most recently applied migration.

Reset()
m.Reset()

Rolls back all applied migrations in reverse order.

ResetAndDrop()
m.ResetAndDrop()

Rolls back all migrations and drops the migrations tracking table.

Version()
m.Version()

Displays the latest applied migration.

Create(name string, index ...int)
// Create next migration automatically
m.Create("add_email_verification")

// Create migration with specific index
m.Create("add_email_verification", 5)

Creates a new migration directory with .up.sql and .down.sql files.

Insert(name string, insertIndex int)
m.Insert("add_missing_index", 3)

Creates a new migration at a specific position, automatically renumbering existing migrations.

Usage Examples

Basic Workflow
m := miggo.New(db, "./migrations")

// 1. Create migrations
m.Create("create_users")
m.Create("create_posts")
m.Create("create_comments")

// 2. Write your SQL in the generated files
// Edit: migrations/001_create_users/*.up.sql and *.down.sql

// 3. Apply migrations
m.Up()

// 4. Check status
m.Version()
// Output: latest migration: 003_create_comments/20240204140000_create_comments.up.sql
Using Standalone Functions

If you prefer not to use the Migrator type:

import "github.com/matheusbastani/miggo"

// Create migration
miggo.Create("./migrations", "add_users", 1)

// Apply migrations
miggo.Up(db, "./migrations")

// Rollback
miggo.Down(db, "./migrations")

// Check version
miggo.Version(db)

// Reset all
miggo.Reset(db, "./migrations")
miggo.ResetAndDrop(db, "./migrations")

// Insert migration
miggo.Insert("./migrations", "add_index", 5)

Database Support

Currently optimized for PostgreSQL, but should work with any database/sql compatible driver that supports:

  • CREATE TABLE IF NOT EXISTS
  • UUID type (or you can modify to use TEXT)
  • Transactions
Using with Other Databases

For MySQL/MariaDB, you may need to adjust the migrations table schema:

CREATE TABLE IF NOT EXISTS migrations (
    id VARCHAR(36) PRIMARY KEY,
    name TEXT UNIQUE NOT NULL,
    applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Best Practices

  1. Always include DOWN migrations - Make your migrations reversible
  2. One logical change per migration - Keep migrations focused and atomic
  3. Test migrations on a copy - Validate both up and down migrations
  4. Don't modify applied migrations - Create a new migration to fix issues
  5. Use transactions - miggo does this automatically, but be aware
  6. Backup before production - Always backup before running migrations in production

Error Handling

miggo uses colored output for clear error reporting:

  • 🟢 Green: Successful operations
  • 🟡 Yellow: Warnings or empty states
  • 🔴 Red: Errors (also exits with status code 1)

All errors are printed to stdout with context about what failed.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details

Acknowledgments

Documentation

Overview

Package migrations provides a simple and flexible SQL migration system. It supports creating, applying, rolling back, and managing database migrations using plain SQL files organized in numbered directories.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Create

func Create(dir, name string, index ...int)

Create creates a new migration directory with up and down SQL files. It automatically generates the next sequential index or uses the provided index.

Parameters:

  • dir: base directory where migrations are stored
  • name: descriptive name for the migration
  • index: optional index number (if not provided, uses next available number)

func Down

func Down(db *sql.DB, baseDir string)

Down rolls back the most recently applied migration. It executes the corresponding .down.sql file and removes the migration record.

Parameters:

  • db: database connection
  • baseDir: base directory containing migration folders

func Insert

func Insert(dir, name string, insertIndex int)

Insert creates a new migration at a specific index, renumbering existing migrations as needed. All migrations with index >= insertIndex will be incremented by 1.

Parameters:

  • dir: base directory where migrations are stored
  • name: descriptive name for the migration
  • insertIndex: the index number where the new migration should be inserted

func Reset

func Reset(db *sql.DB, baseDir string)

Reset rolls back all applied migrations in reverse order. It executes all .down.sql files and removes all migration records.

Parameters:

  • db: database connection
  • baseDir: base directory containing migration folders

func ResetAndDrop

func ResetAndDrop(db *sql.DB, baseDir string)

ResetAndDrop rolls back all migrations and drops the migrations table.

Parameters:

  • db: database connection
  • baseDir: base directory containing migration folders

func Up

func Up(db *sql.DB, baseDir string)

Up applies all pending migrations to the database. It creates the migrations tracking table if it doesn't exist, then runs all .up.sql files that haven't been applied yet.

Parameters:

  • db: database connection
  • baseDir: base directory containing migration folders

func Version

func Version(db *sql.DB)

Version displays the latest applied migration folder. If no migrations have been applied, it displays a message indicating this.

Types

type Migrator

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

Migrator encapsulates the migration configuration and provides convenient methods for running migrations without repeatedly passing the same parameters.

func New

func New(db *sql.DB, baseDir string) *Migrator

New creates a new Migrator instance with the given database connection and base directory for migrations.

Parameters:

  • db: database connection
  • baseDir: base directory containing migration folders

Example:

m := miggo.New(db, "./migrations")
m.Up()
m.Create("add_users_table")

func (*Migrator) Create

func (m *Migrator) Create(name string, index ...int)

Create creates a new migration with the given name. Optionally accepts an index number.

func (*Migrator) Down

func (m *Migrator) Down()

Down rolls back the most recently applied migration.

func (*Migrator) Insert

func (m *Migrator) Insert(name string, insertIndex int)

Insert creates a new migration at a specific index, renumbering existing migrations as needed.

func (*Migrator) Reset

func (m *Migrator) Reset()

Reset rolls back all applied migrations.

func (*Migrator) ResetAndDrop

func (m *Migrator) ResetAndDrop()

ResetAndDrop rolls back all migrations and drops the migrations table.

func (*Migrator) Up

func (m *Migrator) Up()

Up applies all pending migrations.

func (*Migrator) Version

func (m *Migrator) Version()

Version displays the latest applied migration.

Jump to

Keyboard shortcuts

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