93 lines
2.1 KiB
Go
93 lines
2.1 KiB
Go
|
package database
|
|||
|
|
|||
|
import (
|
|||
|
"database/sql"
|
|||
|
"log"
|
|||
|
"net/http"
|
|||
|
"os"
|
|||
|
|
|||
|
vfs "github.com/ailox/migrate-vfs"
|
|||
|
"github.com/golang-migrate/migrate"
|
|||
|
"github.com/golang-migrate/migrate/database/postgres"
|
|||
|
"github.com/jmoiron/sqlx"
|
|||
|
)
|
|||
|
|
|||
|
// GetMigrator returns a Database Migrator for PostgreSQL.
|
|||
|
func getMigrator(db *sql.DB, fs http.FileSystem, path string) (*migrate.Migrate, error) {
|
|||
|
vfsSource, err := vfs.WithInstance(fs, path)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
driver, err := postgres.WithInstance(db, &postgres.Config{})
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
|
|||
|
// the strings are only for logging purpose
|
|||
|
migrator, err := migrate.NewWithInstance(
|
|||
|
// if the linter throws an error here because "source" doesnt
|
|||
|
// match the correct type, this error can be safely ignored.
|
|||
|
"vfs-dir", vfsSource,
|
|||
|
"paul", 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
|
|||
|
)
|
|||
|
|
|||
|
// 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
|
|||
|
var migrationPathInFs string
|
|||
|
|
|||
|
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
|
|||
|
}
|