gormigrate

package module
v1.2.1 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2018 License: MIT Imports: 3 Imported by: 0

README

Gormigrate

GoDoc Go Report Card Build Status Build status

Gormigrate is a migration helper for Gorm. Gorm already has useful migrate functions, just misses proper schema versioning and rollback capabilities.

Supported databases

It supports any of the databases Gorm supports:

  • PostgreSQL
  • MySQL
  • SQLite
  • Microsoft SQL Server

Installing

go get -u gopkg.in/gormigrate.v1

Usage

package main

import (
	"log"

	"gopkg.in/gormigrate.v1"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
)

func main() {
	db, err := gorm.Open("sqlite3", "mydb.sqlite3")
	if err != nil {
		log.Fatal(err)
	}

	db.LogMode(true)

	m := gormigrate.New(db, gormigrate.DefaultOptions, []*gormigrate.Migration{
		// create persons table
		{
			ID: "201608301400",
			Migrate: func(tx *gorm.DB) error {
				// it's a good pratice to copy the struct inside the function,
				// so side effects are prevented if the original struct changes during the time
				type Person struct {
					gorm.Model
					Name string
				}
				return tx.AutoMigrate(&Person{}).Error
			},
			Rollback: func(tx *gorm.DB) error {
				return tx.DropTable("people").Error
			},
		},
		// add age column to persons
		{
			ID: "201608301415",
			Migrate: func(tx *gorm.DB) error {
				// when table already exists, it just adds fields as columns
				type Person struct {
					Age int
				}
				return tx.AutoMigrate(&Person{}).Error
			},
			Rollback: func(tx *gorm.DB) error {
				return tx.Table("people").DropColumn("age").Error
			},
		},
		// add pets table
		{
			ID: "201608301430",
			Migrate: func(tx *gorm.DB) error {
				type Pet struct {
					gorm.Model
					Name     string
					PersonID int
				}
				return tx.AutoMigrate(&Pet{}).Error
			},
			Rollback: func(tx *gorm.DB) error {
				return tx.DropTable("pets").Error
			},
		},
	})

	if err = m.Migrate(); err != nil {
		log.Fatalf("Could not migrate: %v", err)
	}
	log.Printf("Migration did run successfully")
}

Having a separated function for initializing the schema

If you have a lot of migrations, it can be a pain to run all them, as example, when you are deploying a new instance of the app, in a clean database. To prevent this, you can set a function that will run if no migration was run before (in a new clean database). Remember to create everything here, all tables, foreign keys and what more you need in your app.

type Person struct {
	gorm.Model
	Name string
	Age int
}

type Pet struct {
	gorm.Model
	Name     string
	PersonID int
}

m := gormigrate.New(db, gormigrate.DefaultOptions, []*gormigrate.Migration{
    // you migrations here
})

m.InitSchema(func(tx *gorm.DB) error {
	err := tx.AutoMigrate(
		&Person{},
		&Pet{},
		// all other tables of you app
	)
	if err != nil {
		return err
	}

	if err := tx.Model(Pet{}).AddForeignKey("person_id", "people (id)", "RESTRICT", "RESTRICT").Error; err != nil {
		return err
	}
	// all other foreign keys...
	return nil
})

Options

This is the options struct, in case you don't want the defaults:

type Options struct {
	// Migrations table name. Default to "migrations".
	TableName string
	// The name of the column that stores the ID of migrations. Defaults to "id".
	IDColumnName string
	// UseTransaction makes Gormigrate execute migrations inside a single transaction.
	// Keep in mind that not all databases support DDL commands inside transactions.
	// Defaults to false.
	UseTransaction bool
}

Contributing

To run tests, first copy .sample.env as sample.env and edit the connection string of the database you want to run tests against. Then, run tests like below:

# running tests for PostgreSQL
go test -tags postgresql

# running test for MySQL
go test -tags mysql

# running tests for SQLite
go test -tags sqlite

# running tests for SQL Server
go test -tags sqlserver

# running test for multiple databases at once
go test -tags 'sqlite postgresql mysql'

Documentation

Overview

Package gormigrate is a migration helper for Gorm (http://jinzhu.me/gorm/). Gorm already have useful migrate functions (http://jinzhu.me/gorm/database.html#migration), just misses proper schema versioning and rollback cababilities.

Example:

package main

import (
    "log"

    "github.com/go-gormigrate/gormigrate"
    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/sqlite"
)

type Person struct {
    gorm.Model
    Name string
}

type Pet struct {
    gorm.Model
    Name     string
    PersonID int
}

func main() {
    db, err := gorm.Open("sqlite3", "mydb.sqlite3")
    if err != nil {
        log.Fatal(err)
    }
    if err = db.DB().Ping(); err != nil {
        log.Fatal(err)
    }

    db.LogMode(true)

    m := gormigrate.New(db, gormigrate.DefaultOptions, []*gormigrate.Migration{
        {
            ID: "201608301400",
            Migrate: func(tx *gorm.DB) error {
                return tx.AutoMigrate(&Person{}).Error
            },
            Rollback: func(tx *gorm.DB) error {
                return tx.DropTable("people").Error
            },
        },
        {
            ID: "201608301430",
            Migrate: func(tx *gorm.DB) error {
                return tx.AutoMigrate(&Pet{}).Error
            },
            Rollback: func(tx *gorm.DB) error {
                return tx.DropTable("pets").Error
            },
        },
    })

    err = m.Migrate()
    if err == nil {
        log.Printf("Migration did run successfully")
    } else {
        log.Printf("Could not migrate: %v", err)
    }
}

Index

Constants

This section is empty.

Variables

View Source
var (
	// DefaultOptions can be used if you don't want to think about options.
	DefaultOptions = &Options{
		TableName:      "migrations",
		IDColumnName:   "id",
		IDColumnSize:   255,
		UseTransaction: false,
	}

	// ErrRollbackImpossible is returned when trying to rollback a migration
	// that has no rollback function.
	ErrRollbackImpossible = errors.New("gormigrate: It's impossible to rollback this migration")

	// ErrNoMigrationDefined is returned when no migration is defined.
	ErrNoMigrationDefined = errors.New("gormigrate: No migration defined")

	// ErrMissingID is returned when the ID od migration is equal to ""
	ErrMissingID = errors.New("gormigrate: Missing ID in migration")

	// ErrNoRunnedMigration is returned when any runned migration was found while
	// running RollbackLast
	ErrNoRunnedMigration = errors.New("gormigrate: Could not find last runned migration")
)

Functions

This section is empty.

Types

type DuplicatedIDError added in v1.1.4

type DuplicatedIDError struct {
	ID string
}

DuplicatedIDError is returned when more than one migration have the same ID

func (*DuplicatedIDError) Error added in v1.1.4

func (e *DuplicatedIDError) Error() string

type Gormigrate

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

Gormigrate represents a collection of all migrations of a database schema.

func New

func New(db *gorm.DB, options *Options, migrations []*Migration) *Gormigrate

New returns a new Gormigrate.

func (*Gormigrate) InitSchema added in v1.1.0

func (g *Gormigrate) InitSchema(initSchema InitSchemaFunc)

InitSchema sets a function that is run if no migration is found. The idea is preventing to run all migrations when a new clean database is being migrating. In this function you should create all tables and foreign key necessary to your application.

func (*Gormigrate) Migrate

func (g *Gormigrate) Migrate() error

Migrate executes all migrations that did not run yet.

func (*Gormigrate) MigrateTo added in v1.2.1

func (g *Gormigrate) MigrateTo(migrationID string) error

MigrateTo executes all migrations that did not run yet up to the migration that matches `migrationID`.

func (*Gormigrate) RollbackLast

func (g *Gormigrate) RollbackLast() error

RollbackLast undo the last migration

func (*Gormigrate) RollbackMigration

func (g *Gormigrate) RollbackMigration(m *Migration) error

RollbackMigration undo a migration.

func (*Gormigrate) RollbackTo added in v1.2.1

func (g *Gormigrate) RollbackTo(migrationID string) error

RollbackTo undoes migrations up to the given migration that matches the `migrationID`. Migration with the matching `migrationID` is not rolled back.

type InitSchemaFunc added in v1.1.0

type InitSchemaFunc func(*gorm.DB) error

InitSchemaFunc is the func signature for initializing the schema.

type MigrateFunc

type MigrateFunc func(*gorm.DB) error

MigrateFunc is the func signature for migrating.

type Migration

type Migration struct {
	// ID is the migration identifier. Usually a timestamp like "201601021504".
	ID string
	// Migrate is a function that will br executed while running this migration.
	Migrate MigrateFunc
	// Rollback will be executed on rollback. Can be nil.
	Rollback RollbackFunc
}

Migration represents a database migration (a modification to be made on the database).

type Options

type Options struct {
	// TableName is the migration table.
	TableName string
	// IDColumnName is the name of column where the migration id will be stored.
	IDColumnName string
	// IDColumnSize is the length of the migration id column
	IDColumnSize int
	// UseTransaction makes Gormigrate execute migrations inside a single transaction.
	// Keep in mind that not all databases support DDL commands inside transactions.
	UseTransaction bool
}

Options define options for all migrations.

type RollbackFunc

type RollbackFunc func(*gorm.DB) error

RollbackFunc is the func signature for rollbacking.

Jump to

Keyboard shortcuts

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