83 lines
1.8 KiB
Go
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
|
|
}
|