skeleton/internal/database/migrate.go
2020-07-21 22:50:11 +02:00

102 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package database
import (
"database/sql"
"log"
"net/http"
"os"
"github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/database/postgres"
"github.com/golang-migrate/migrate/v4/source/httpfs"
"github.com/jmoiron/sqlx"
)
// GetMigrator returns a Database Migrator for PostgreSQL for the supplied
// http.FileSystem and path.
func getMigrator(db *sql.DB, fs http.FileSystem, path string) (*migrate.Migrate, error) {
driver, err := postgres.WithInstance(db, &postgres.Config{})
if err != nil {
return nil, err
}
migrations, err := httpfs.New(fs, path)
if err != nil {
return nil, err
}
// the strings are only for logging purpose
migrator, err := migrate.NewWithInstance(
"assets", migrations,
"database", driver,
)
if err != nil {
return nil, err
}
return migrator, err
}
type wrappedLogger struct {
*log.Logger
}
func (l wrappedLogger) Verbose() bool {
return true
}
const (
// MigrateDrop is the revision number that will cause all tables to be
// dropped from the database.
MigrateDrop = -3
// MigrateUp is the revision number that will cause the database to be
// migrated to the very latest revision.
MigrateUp = -1
)
// GetCurrentMigration returns the currently active migration version.
// If no migration has been applied yet, it will return ErrNilVersion.
func GetCurrentMigration(db *sqlx.DB) (version uint, dirty bool, err error) {
migrator, err := getMigrator(db.DB, http.Dir("/invalid/path/unused"), "/unused")
if err != nil {
return 0, false, err
}
return migrator.Version()
}
// Migrate Migrates the schema of the supplied Database. Supported
// methods are:
// * database.MigrateUp Migrate to the latest version
// * database.MigrateDrop empty everything
// * `(integer)` Migrate to specific version
func Migrate(db *sqlx.DB, fs http.FileSystem, revision int) error {
// migrate database
const migrationPathInFs = "/migrations"
migrator, err := getMigrator(db.DB, fs, migrationPathInFs)
if err != nil {
return err
}
wl := wrappedLogger{log.New(os.Stdout, "[MIGRATIONS] ", log.LstdFlags)}
migrator.Log = wl
switch revision {
case MigrateUp:
err = migrator.Up()
case MigrateDrop:
err = migrator.Drop()
default:
err = migrator.Migrate(uint(revision))
}
if err == migrate.ErrNoChange {
wl.Println("no change")
} else if err != nil {
return err
}
return nil
}