embed_tern/migrations/migrations.go
2023-03-05 09:08:01 +10:30

83 lines
1.8 KiB
Go

package migrations
import (
"context"
"embed"
"fmt"
"io/fs"
"github.com/jackc/pgx/v5"
"github.com/jackc/tern/v2/migrate"
)
const versionTable = "db_version"
type Migrator struct {
migrator *migrate.Migrator
}
//go:embed data/*.sql
var migrationFiles embed.FS
func NewMigrator(dbDNS string) (Migrator, error) {
conn, err := pgx.Connect(context.Background(), dbDNS)
if err != nil {
return Migrator{}, err
}
migrator, err := migrate.NewMigratorEx(context.Background(), conn, versionTable, &migrate.MigratorOptions{
DisableTx: false,
})
if err != nil {
return Migrator{}, err
}
migrationRoot, _ := fs.Sub(migrationFiles, "data")
err = migrator.LoadMigrations(migrationRoot)
if err != nil {
return Migrator{}, err
}
return Migrator{
migrator: migrator,
}, nil
}
// Info the current migration version and the embedded maximum migration, and a textual
// representation of the migration state for informational purposes.
func (m Migrator) Info() (int32, int32, string, error) {
version, err := m.migrator.GetCurrentVersion(context.Background())
if err != nil {
return 0, 0, "", err
}
info := ""
var last int32
for _, thisMigration := range m.migrator.Migrations {
last = thisMigration.Sequence
cur := version == thisMigration.Sequence
indicator := " "
if cur {
indicator = "->"
}
info = info + fmt.Sprintf("%2s %3d %s\n", indicator, thisMigration.Sequence, thisMigration.Name)
}
return version, last, info, nil
}
// Migrate migrates the DB to the most recent version of the schema.
func (m Migrator) Migrate() error {
err := m.migrator.Migrate(context.Background())
return err
}
// MigrateTo migrates to a specific version of the schema. Use '0' to undo all migrations.
func (m Migrator) MigrateTo(ver int32) error {
err := m.migrator.MigrateTo(context.Background(), ver)
return err
}