bedrock-migrate

module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jan 7, 2026 License: MIT

README

bedrock-migrate

A flexible database migration tool for PostgreSQL and MongoDB, written in Go. Works both as a standalone CLI and as an embeddable library.

Features

  • Multi-Database Support: PostgreSQL and MongoDB
  • Dual Usage: Standalone CLI or embeddable library
  • Transaction Safety: PostgreSQL migrations run in transactions
  • Migration Tracking: Prevents re-applying migrations
  • Flexible Commands: Apply/revert migrations by count or version
  • Dry Run Mode: Preview changes before applying
  • Colored Output: Easy-to-read status messages
  • Verbose Logging: Detailed execution information

Installation

As a Standalone CLI
go install github.com/Jack4Code/bedrock-migrate/cmd/migrate@latest

Or build from source:

git clone https://github.com/Jack4Code/bedrock-migrate.git
cd bedrock-migrate
go build -o migrate ./cmd/migrate
sudo mv migrate /usr/local/bin/
As a Library
go get github.com/Jack4Code/bedrock-migrate

Configuration

PostgreSQL

Configure using environment variables:

Option 1: Connection URL

export DATABASE_URL="postgresql://user:password@localhost:5432/dbname?sslmode=disable"

Option 2: Individual Variables

export PG_HOST=localhost
export PG_PORT=5432
export PG_USER=postgres
export PG_PASSWORD=yourpassword
export PG_DATABASE=mydb
MongoDB

Configure using environment variables:

Option 1: Connection URL

export MONGO_URL="mongodb://user:password@localhost:27017"
export MONGO_DATABASE=mydb

Option 2: Individual Variables

export MONGO_HOST=localhost
export MONGO_PORT=27017
export MONGO_USER=admin
export MONGO_PASSWORD=yourpassword
export MONGO_DATABASE=mydb

Usage

CLI Commands
Create a New Migration
# PostgreSQL
migrate create add_users_table --type postgres

# MongoDB
migrate create add_users_collection --type mongo

This creates two files:

  • migrations/postgres/20240101120000_add_users_table.up.sql
  • migrations/postgres/20240101120000_add_users_table.down.sql
Apply Migrations
# Apply all pending migrations
migrate up --type postgres

# Apply migrations up to a specific version
migrate up --to 20240101120000 --type postgres

# Apply next N migrations
migrate up -n 2 --type postgres

# Dry run (show what would be applied)
migrate up --dry-run --type postgres

# Verbose output
migrate up -v --type postgres
Revert Migrations
# Revert last migration
migrate down --type postgres

# Revert migrations down to a specific version
migrate down --to 20240101120000 --type postgres

# Revert last N migrations
migrate down -n 2 --type postgres

# Dry run (show what would be reverted)
migrate down --dry-run --type postgres
Check Migration Status
migrate status --type postgres

Example output:

Migration Status:
=================
Version              Name                                     Status
------------------------------------------------------------
20240101120000       create_users_table                      APPLIED
20240102150000       add_products_table                      PENDING
------------------------------------------------------------
Total: 2 | Applied: 1 | Pending: 1
Show Current Version
migrate version --type postgres
Using as a Library

You can embed bedrock-migrate commands into your own application:

package main

import (
    "github.com/Jack4Code/bedrock-migrate/pkg/commands"
    "github.com/spf13/cobra"
)

func main() {
    rootCmd := &cobra.Command{
        Use:   "myapp",
        Short: "My application",
    }

    // Add the migrate command to your app
    rootCmd.AddCommand(commands.MigrateCommand())

    // Add other commands...
    // rootCmd.AddCommand(otherCommand())

    rootCmd.Execute()
}

Now you can run:

myapp migrate up --type postgres
myapp migrate status --type postgres
Programmatic Usage

You can also use the migration library programmatically:

package main

import (
    "log"
    "github.com/Jack4Code/bedrock-migrate/pkg/migration"
)

func main() {
    // Create a PostgreSQL driver
    driver, err := migration.NewPostgresDriver()
    if err != nil {
        log.Fatal(err)
    }
    defer driver.Close()

    // Create a migration manager
    config := &migration.Config{
        MigrationsDir: "./migrations",
        DBType:        "postgres",
        Verbose:       true,
        DryRun:        false,
    }
    manager := migration.NewManager(driver, config)

    // Apply all pending migrations
    if err := manager.MigrateUp(0, 0); err != nil {
        log.Fatal(err)
    }

    // Get current version
    version, err := manager.GetCurrentVersion()
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Current version: %d\n", version)
}

Migration Files

Directory Structure
migrations/
├── postgres/
│   ├── 20240101120000_create_users_table.up.sql
│   ├── 20240101120000_create_users_table.down.sql
│   ├── 20240102150000_add_products_table.up.sql
│   └── 20240102150000_add_products_table.down.sql
└── mongo/
    ├── 20240101120000_create_users_collection.up.js
    ├── 20240101120000_create_users_collection.down.js
    ├── 20240102150000_add_products_collection.up.js
    └── 20240102150000_add_products_collection.down.js
PostgreSQL Migration Example

20240101120000_create_users_table.up.sql

-- Create users table
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    email VARCHAR(255) UNIQUE NOT NULL,
    username VARCHAR(100) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Create index on email
CREATE INDEX idx_users_email ON users(email);

20240101120000_create_users_table.down.sql

-- Drop users table
DROP TABLE IF EXISTS users;
MongoDB Migration Example

20240101120000_create_users_collection.up.js

// Create users collection with validation
db.createCollection("users", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["email", "username"],
      properties: {
        email: {
          bsonType: "string",
          description: "must be a string and is required"
        },
        username: {
          bsonType: "string",
          description: "must be a string and is required"
        }
      }
    }
  }
});

// Create indexes
db.users.createIndex({ email: 1 }, { unique: true });

20240101120000_create_users_collection.down.js

// Drop users collection
db.users.drop();

Migration Tracking

PostgreSQL

Creates a schema_migrations table:

CREATE TABLE schema_migrations (
    version BIGINT PRIMARY KEY,
    applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
MongoDB

Creates a schema_migrations collection with documents:

{
    version: 20240101120000,
    applied_at: ISODate("2024-01-01T12:00:00Z")
}

Command-Line Flags

Global Flags
  • --dir <path>: Migrations directory (default: ./migrations)
  • --type <db>: Database type (postgres or mongo) - required
  • -v, --verbose: Enable verbose output
  • --dry-run: Show what would happen without executing
Command-Specific Flags

up command:

  • --to <version>: Apply migrations up to this version
  • -n <count>: Apply next N migrations

down command:

  • --to <version>: Revert migrations down to this version
  • -n <count>: Revert last N migrations

Best Practices

  1. Always write down migrations: Every up migration should have a corresponding down migration
  2. Test migrations: Use --dry-run to preview changes before applying
  3. Use transactions: PostgreSQL migrations automatically run in transactions
  4. Version control: Commit migration files to your repository
  5. Backup your data: Always backup before running migrations in production
  6. Sequential migrations: Don't modify existing migration files after they've been applied

Error Handling

  • Migrations run in transactions (PostgreSQL) - failed migrations will rollback
  • Clear error messages indicate which migration failed and why
  • Migration tracking ensures failed migrations aren't marked as applied
  • Use --verbose flag for detailed error information

Development

Building
go build -o migrate ./cmd/migrate
Running Tests
go test ./...
Project Structure
bedrock-migrate/
├── cmd/
│   └── migrate/
│       └── main.go          # CLI entry point
├── pkg/
│   ├── commands/            # Cobra commands (exportable)
│   │   ├── root.go
│   │   ├── create.go
│   │   ├── up.go
│   │   ├── down.go
│   │   ├── status.go
│   │   └── version.go
│   └── migration/           # Core migration logic
│       ├── migration.go     # Interfaces and manager
│       ├── postgres.go      # PostgreSQL driver
│       └── mongo.go         # MongoDB driver
└── migrations/              # Example migrations
    ├── postgres/
    └── mongo/

Contributing

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

License

MIT License - see LICENSE file for details

Support

For issues and questions:

  • Open an issue on GitHub
  • Check existing documentation

Changelog

v1.0.0
  • Initial release
  • PostgreSQL support
  • MongoDB support
  • CLI and library usage
  • Migration tracking
  • Dry-run mode
  • Colored output

Directories

Path Synopsis
cmd
migrate command
pkg

Jump to

Keyboard shortcuts

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