migrate

package module
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Apr 2, 2024 License: MIT Imports: 13 Imported by: 21

README

Versioned migrations for MongoDB

Build Status codecov Go Report Card GoDoc

This package allows to perform versioned migrations on your MongoDB using mongo-go-driver. Inspired by go-pg migrations.

Table of Contents

Prerequisites

  • Golang >= 1.22

Installation

go get -v -u github.com/xakep666/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 (
  "context"

  "go.mongodb.org/mongo-driver/bson"
  "go.mongodb.org/mongo-driver/mongo"
  "go.mongodb.org/mongo-driver/mongo/options"
  migrate "github.com/xakep666/mongo-migrate"
)

func init() {
  migrate.MustRegister(func(ctx context.Context, db *mongo.Database) error {
    opt := options.Index().SetName("my-index")
    keys := bson.D{{Key: "my-key", Value: 1}}
    model := mongo.IndexModel{Keys: keys, Options: opt}
    _, err := db.Collection("my-coll").Indexes().CreateOne(ctx, model)
    if err != nil {
      return err
    }
    return nil
  }, func(ctx context.Context, db *mongo.Database) error {
    _, err := db.Collection("my-coll").Indexes().DropOne(ctx, "my-index")
    if err != nil {
      return err
    }
    return nil
  })
}
  • Import it in your application.
import (
    ...
    migrate "github.com/xakep666/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)
	ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
	defer cancel()
	client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri))
	if err != nil {
		return nil, err
	}
	db := client.Database(database)
	migrate.SetDatabase(db)
	if err := migrate.Up(ctx, 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)
	ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
	defer cancel()
	err = mongo.Connect(ctx, opt)
	if err != nil {
		return nil, err
	}
	db = client.Database(database)
	m := migrate.NewMigrate(db, migrate.Migration{
		Version: 1,
		Description: "add my-index",
		Up: func(ctx context.Context, 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(ctx, model)
			if err != nil {
				return err
			}

			return nil
		},
		Down: func(ctx context.Context, db *mongo.Database) error {
			_, err := db.Collection("my-coll").Indexes().DropOne(ctx, "my-index")
			if err != nil {
				return err
			}
			return nil
		},
	})
	if err := m.Up(ctx, 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. In this collection stored documents like

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

Current database version determined as version from latest inserted document.

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

License

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

Documentation

Overview

Package migrate allows to perform versioned migrations in your MongoDB.

Index

Constants

View Source
const AllAvailable = -1

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

Variables

This section is empty.

Functions

func Down

func Down(ctx context.Context, n int) error

Down performs "down" migration using registered migrations. Detailed description available in Migrate.Down().

func MustRegister

func MustRegister(up, down MigrationFunc)

MustRegister acts like Register but panics on errors.

func Register

func Register(up, down MigrationFunc) error

Register performs migration registration. Use case of this function:

- Create a file called like "1_setup_indexes.go" ("<version>_<comment>.go").

- Use the following template inside:

 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/xakep666/mongo-migrate"
 )

 func init() {
	 migrate.Register(func(db *mongo.Database) error {
	 	 opt := options.Index().SetName("my-index")
	 	 keys := bson.D{{Key: "my-key", Value: 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
	 })
 }

func SetDatabase

func SetDatabase(db *mongo.Database)

SetDatabase sets database for global migrate.

func SetLogger added in v0.3.0

func SetLogger(log Logger)

SetLogger sets a logger to print the migration process

func SetMigrationsCollection

func SetMigrationsCollection(name string)

SetMigrationsCollection changes default collection name for migrations history.

func Up

func Up(ctx context.Context, n int) error

Up performs "up" migration using registered migrations. Detailed description available in Migrate.Up().

func Version

func Version(ctx context.Context) (uint64, string, error)

Version returns current database version.

Types

type DefaultLogger added in v0.3.0

type DefaultLogger struct{}

func (DefaultLogger) Printf added in v0.3.0

func (l DefaultLogger) Printf(msg string, args ...any)

type Logger added in v0.3.0

type Logger interface {
	Printf(format string, args ...any)
}

type Migrate

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

Migrate is type for performing migrations in provided database. Database versioned using dedicated collection. Each migration applying ("up" and "down") adds new document to collection. This document consists migration version, migration description and timestamp. Current database version determined as version in latest added document (biggest "_id") from collection mentioned above.

func NewMigrate

func NewMigrate(db *mongo.Database, migrations ...Migration) *Migrate

func (*Migrate) Down

func (m *Migrate) Down(ctx context.Context, n int) error

Down performs "down" migration to the oldest available version. If n<=0 all "down" migrations with older version will be performed. If n>0 only n migrations with older version will be performed.

func (*Migrate) SetLogger added in v0.3.0

func (m *Migrate) SetLogger(log Logger)

SetLogger sets a logger to print the migration process

func (*Migrate) SetMigrationsCollection

func (m *Migrate) SetMigrationsCollection(name string)

SetMigrationsCollection replaces name of collection for storing migration information. By default, it is "migrations".

func (*Migrate) SetVersion

func (m *Migrate) SetVersion(ctx context.Context, version uint64, description string) error

SetVersion forcibly changes database version to provided one.

func (*Migrate) Up

func (m *Migrate) Up(ctx context.Context, n int) error

Up performs "up" migrations to latest available version. If n<=0 all "up" migrations with newer versions will be performed. If n>0 only n migrations with newer version will be performed.

func (*Migrate) Version

func (m *Migrate) Version(ctx context.Context) (uint64, string, error)

Version returns current database version and comment.

type Migration

type Migration struct {
	Version     uint64
	Description string
	Up          MigrationFunc
	Down        MigrationFunc
}

Migration represents single database migration. Migration contains:

- version: migration version, must be unique in migration list

- description: text description of migration

- up: callback which will be called in "up" migration process

- down: callback which will be called in "down" migration process for reverting changes

func RegisteredMigrations

func RegisteredMigrations() []Migration

RegisteredMigrations returns all registered migrations.

type MigrationFunc

type MigrationFunc func(ctx context.Context, db *mongo.Database) error

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

Jump to

Keyboard shortcuts

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