90 lines
2 KiB
Go
90 lines
2 KiB
Go
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
|
||
)
|
||
|
||
// 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
|
||
}
|