Categorygithub.com/SoftSwiss/mongo-migrate
modulepackage
1.0.0
Repository: https://github.com/softswiss/mongo-migrate.git
Documentation: pkg.go.dev

# README

Versioned migrations for MongoDB

Build Status codecov Go Report Card GoDoc License: MIT

This package allows to perform versioned migrations on your MongoDB using mongo-go-driver. Based on mongo-migrate.

Table of Contents

Prerequisites

  • Golang >= 1.10 or Vgo

Installation

go get -v -u github.com/SoftSwiss/mongo-migrate

Usage

Use case #1. Migrations in files.

  • Create a package with migration files. File name should be like <version>_<description>.go.

1_add-my-index.go

package migrations

import (
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	migrate "github.com/SoftSwiss/mongo-migrate"
)

func init() {
	migrate.Register(func(db *mongo.Database) error {
		opt := options.Index().SetName("my-index")
		keys := bson.D{{"my-key", 1}}
		model := mongo.IndexModel{Keys: keys, Options: opt}
		_, err := db.Collection("my-coll").Indexes().CreateOne(context.TODO(), model)
		if err != nil {
			return err
		}

		return nil
	}, func(db *mongo.Database) error {
		_, err := db.Collection("my-coll").Indexes().DropOne(context.TODO(), "my-index")
		if err != nil {
			return err
		}
		return nil
	})
}
  • Import it in your application.
import (
    ...
    migrate "github.com/SoftSwiss/mongo-migrate"
    _ "path/to/migrations_package" // database migrations
    ...
)
  • Run migrations.
func MongoConnect(host, user, password, database string) (*mongo.Database, error) {
	uri := fmt.Sprintf("mongodb://%s:%s@%s:27017", user, password, host)
	opt := options.Client().ApplyURI(uri)
	client, err := mongo.NewClient(opt)
	if err != nil {
		return nil, err
	}
	ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
	defer cancel()
	err = client.Connect(ctx)
	if err != nil {
		return nil, err
	}
	db = client.Database(database)
	migrate.SetDatabase(db)
	if err := migrate.Up(migrate.AllAvailable); err != nil {
		return nil, err
	}
	return db, nil
}

Use case #2. Migrations in application code.

  • Just define it anywhere you want and run it.
func MongoConnect(host, user, password, database string) (*mongo.Database, error) {
	uri := fmt.Sprintf("mongodb://%s:%s@%s:27017", user, password, host)
	opt := options.Client().ApplyURI(uri)
	client, err := mongo.NewClient(opt)
	if err != nil {
		return nil, err
	}
	ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
	defer cancel()
	err = client.Connect(ctx)
	if err != nil {
		return nil, err
	}
	db = client.Database(database)
	m := migrate.NewMigrate(db, migrate.Migration{
		Version: 1,
		Description: "add my-index",
		Up: func(db *mongo.Database) error {
			opt := options.Index().SetName("my-index")
			keys := bson.D{{"my-key", 1}}
			model := mongo.IndexModel{Keys: keys, Options: opt}
			_, err := db.Collection("my-coll").Indexes().CreateOne(context.TODO(), model)
			if err != nil {
				return err
			}

			return nil
		},
		Down: func(db *mongo.Database) error {
			_, err := db.Collection("my-coll").Indexes().DropOne(context.TODO(), "my-index")
			if err != nil {
				return err
			}
			return nil
		},
	})
	if err := m.Up(migrate.AllAvailable); err != nil {
		return nil, err
	}
	return db, nil
}

How it works?

This package creates a special collection (by default it`s name is "migrations") for versioning. For each applied migration in this collection is being stored a document like

{
    "_id": "<mongodb-generated id>",
    "version": 1,
    "description": "add my-index",
    "timestamp": "<when applied>"
}

When you roll back then corresponding documents are being removed from the collection. Migration versions must be unique.

You can change collection name using SetMigrationsCollection method. Remember that if you want to use custom collection name you need to set it before running migrations.

Running tests

MONGO_URL=mongodb://[username]:[password]@[host]:[port]/[test_database] go test *.go

License

mongo-migrate project is licensed under the terms of the MIT license. Please see LICENSE in this repository for more details.

# Functions

Down performs "down" migration using registered migrations.
IsMigrated returns true if all migrations have been migrated, false otherwise.
MustRegister acts like Register but panics on errors.
No description provided by the author
Register performs migration registration.
RegisteredMigrations returns all registered migrations.
SetDatabase sets database for global migrate.
SetMigrationsCollection changes default collection name for migrations history.
Up performs "up" migration using registered migrations.

# Constants

AllAvailable used in "Up" or "Down" methods to run all available migrations.

# Structs

Migrate is type for performing migrations in provided database.
Migration represents single database migration.

# Type aliases

MigrationFunc used to define actions to be performed for a migration.