Skip to content
/ up Public

A simple, zero dependency, database agnostic, migration tool for Go projects

License

Notifications You must be signed in to change notification settings

tomasruud/up

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Up

A simple, zero dependency, database agnostic, migration library for Go projects.

Up, as the name suggests, only supports migrations in a single direction. This means that a migration can never be rolled back. If you need to revert a change, you have to append a new migration that reverts your previous change. If you need to be able to migrate down, this library is probably not for you.

Check out the complete docs at https://go.dev/pkg/github.com/tomasruud/up

Usage

Minimal

Below is a minimal example on how migrations for a SQLite database could be done.

package main

import (
	"database/sql"
	"log"

	"github.com/tomasruud/up"
	_ "modernc.org/sqlite"
)

func main() {
	db, _ := sql.Open("sqlite", ":memory:")

	migrator := up.Migrator{
		StateStore: up.SQLiteStore{},
		Migrations: []up.Migration{
			func(tx *sql.Tx) error {
				_, err := tx.Exec(`create table users(id text primary key)`)
				return err
			},

			func(tx *sql.Tx) error {
				_, err := tx.Exec(`alter table users add column name text`)
				return err
			},
		},
	}

	if err := migrator.Migrate(db); err != nil {
		log.Fatalf("Unable to run migrations: %v", err)
	}

	log.Println("Migrations done")
}

Full

Below is a full example on how this library could be used, including using callback hooks for doing logging. This example uses the provided StateStore for SQLite, but you are free to make your own implementation that suit your needs.

package main

import (
	"database/sql"
	"log"

	"github.com/tomasruud/up"
	_ "modernc.org/sqlite"
)

func main() {
	db, _ := sql.Open("sqlite", ":memory:")

	migrations := []up.Migration{
		func(tx *sql.Tx) error {
			_, err := tx.Exec(`create table users(id text primary key)`)
			return err
		},

		func(tx *sql.Tx) error {
			_, err := tx.Exec(`alter table users add column name text`)
			return err
		},
	}

	migrator := up.Migrator{
		StateStore: up.SQLiteStore{},
		Migrations: migrations,

		OnSetupComplete: func(start int, last *int) {
			if last == nil {
				log.Printf("Migrations initialized, no migrations have run")
				return
			}

			log.Printf("Migrations initialized, latest migration is %d", *last)
		},

		OnMigrationDone: func(current int, start int) {
			log.Printf("Migration %d/%d done", current+1+start, len(migrations)-start)
		},
	}

	if err := migrator.Migrate(db); err != nil {
		log.Fatalf("Unable to run migrations: %v", err)
	}

	log.Println("Migrations done")
}

About

A simple, zero dependency, database agnostic, migration tool for Go projects

Topics

Resources

License

Stars

Watchers

Forks

Languages