gormigrator

package module
v1.1.1 Latest Latest
Warning

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

Go to latest
Published: Sep 1, 2021 License: MIT Imports: 9 Imported by: 0

README

GORMigrator v1 - A migration tool based on GORM

The GORMigrator is a lightweight but powerful and flexible migration tool based on GORM. Especially useful in container environments like Docker.

The goal is to create a build of your migration setup.

GORMigrator can also be used as a seeder.

Steps for deployment

  • Create a go build
  • Putting build in a FROM scratch AS bin container for minimal size
  • Deploy
  • Start service or container with environment variables (FROM=null TO=create_user_table USER=testuser ... to perform migration on database

Example

See example under example/ to see how it works.

The folder looks like

├── migration
│   ├── main.go
│   ├── mig00001.go
│   ├── mig00002.go
│   └── mig00003.go
    ...

mig-files can have any names, as long as they are ordered (e.g. mig000xx.go). Example for main.go:

package main

import (
	"fmt"

	g "github.com/randree/gormigrator"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

func main() {
	db, err := gorm.Open(postgres.Open("host=localhost user=user password=passpass dbname=testdb port=5432 sslmode=disable"))
	if err != nil {
		fmt.Println(err.Error())
	}

	g.InitMigration(db, "migrations") //"migrations" is the name of the table
}

mig-files (e.g. mig001.go) looks like:

package main

import (
	g "github.com/randree/gormigrator"
	"gorm.io/gorm"
)

func init() {

	// Mig function to load state 
	g.Mig(g.State{

		// Tag: Name for state after migration
		Tag: "roles",

		// Up-function to migrate up
		Up: func(db *gorm.DB) error {

			type Role struct {
				ID   int `gorm:"primarykey"`
				Role string
			}
			db.AutoMigrate(&Role{})
			err := db.Create(&Role{
				ID:   2,
				Role: "Guest",
			}).Error

			return err
		},

		// Down-function to migrate down
		Down: func(db *gorm.DB) error {
			err := db.Migrator().DropTable("roles")
			return err
		},
	})
}

Create and use module

Steps to create a go module:

$ go mod init migration

To load dependencies:

$ go mod tidy

To run a migration:

$ FROM=null TO=users USER=foo go run ./...

⬆ UPGRADE (0) ⟶ (mig00001.go) tag: null ⟶ roles 
⬆ UPGRADE (mig00001.go) ⟶ (mig00002.go) tag: roles ⟶ customers 
⬆ UPGRADE (mig00002.go) ⟶ (mig00003.go) tag: customers ⟶ users

To initialize first tables you start migration from a tag with name null.

To show a migration history:

$ HISTORY=1 go run ./...

| DATETIME HISTORY                       | LEVEL (State)         | USER       |
| -------------------------------------- | --------------------- | ---------- |
| 2021-08-31 13:09:47.932619 +0200 CEST  | mig00003.go (current) | foo        |
| 2021-08-31 13:09:47.908876 +0200 CEST  | mig00002.go           | foo        |
| 2021-08-31 13:09:47.871357 +0200 CEST  | mig00001.go           | foo        |

To show version:

$ VERSION=1 go run ./...

Gormigrator version:  1.0.0

Or combine all:

$ VERSION=1 HISTORY=1 FROM=users TO=testers USER=foo go run ./...

(HISTORY gives you the the list of migrations before any action)

Calls
$ FROM=<Tag> TO=<Tag> [HISTORY=1] [VERSION=1] (Docker Container | go build | go run ./...)

Docker-compose file

...
  migrator:
    image: from_scratch_image
    environment:
      FROM: <Tag>
      TO: <Tag>
...

Downgrade note

To prevent a accidental and fatal downgrade to null or too many steps in a row only one downgrade step at a time is allowed.

References

Documentation

Index

Constants

View Source
const Version = "1.1.0"

Variables

View Source
var Testing bool = false

Functions

func InitMigration

func InitMigration(db *gorm.DB, tablename string)

func Mig

func Mig(state State)

Types

type Migration

type Migration struct {
	gorm.Model
	Tag   string `gorm:"size:455"`
	Level string `gorm:"size:255"`
	User  string `gorm:"size:255"`
}

Migration model

type MigrationStore

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

func NewMigrationStore

func NewMigrationStore(db *gorm.DB, tableName string) *MigrationStore

func (*MigrationStore) FetchAll

func (m *MigrationStore) FetchAll() ([]*Migration, error)

func (*MigrationStore) GetCurrentTag

func (m *MigrationStore) GetCurrentTag() (string, error)

GetCurrentLevel returns the current level. In our case it is the filename, e.g. "mig0032.go"

func (*MigrationStore) SaveState

func (m *MigrationStore) SaveState(tag, level, user string) error

type State

type State struct {
	Tag   string
	Level string
	Up    func(*gorm.DB) error
	Down  func(*gorm.DB) error
}

Jump to

Keyboard shortcuts

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