Open one pgx stdlib *sql.DB, hand it to GORM, and run per-plugin gormigrate sets with isolated history tables after an ICU pl-PL check. Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
2.4 KiB
Go
87 lines
2.4 KiB
Go
package lagoon
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"git.golem15.com/golem15/summercms/backpack"
|
|
"git.golem15.com/golem15/summercms/bonfire"
|
|
"git.golem15.com/golem15/summercms/party"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// RuntimeCommands returns migrate, migrate:rollback and migrate:status.
|
|
// Serve is registered once the HTTP layer exists.
|
|
func RuntimeCommands(app *backpack.App, plugins []party.Plugin) []bonfire.Command {
|
|
return []bonfire.Command{
|
|
{
|
|
Name: "migrate",
|
|
Description: "Run plugin migrations in dependency order",
|
|
Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error {
|
|
return withDB(ctx, app, func(gdb *gorm.DB) error {
|
|
if err := Migrate(gdb, plugins); err != nil {
|
|
return err
|
|
}
|
|
out.Success("migrations applied")
|
|
return nil
|
|
})
|
|
},
|
|
},
|
|
{
|
|
Name: "migrate:rollback",
|
|
Description: "Roll back the last migration of a plugin",
|
|
Flags: []bonfire.Flag{{
|
|
Name: "plugin",
|
|
Description: "Plugin ID whose last migration to roll back",
|
|
}},
|
|
Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error {
|
|
plugin, _ := in.Flag("plugin")
|
|
return withDB(ctx, app, func(gdb *gorm.DB) error {
|
|
if err := RollbackLast(gdb, plugins, plugin); err != nil {
|
|
return err
|
|
}
|
|
if plugin == "" {
|
|
plugin = lastMigrationPlugin(plugins)
|
|
}
|
|
out.Success(fmt.Sprintf("rolled back last migration of %s", plugin))
|
|
return nil
|
|
})
|
|
},
|
|
},
|
|
{
|
|
Name: "migrate:status",
|
|
Description: "Show per-plugin migration history",
|
|
Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error {
|
|
return withDB(ctx, app, func(gdb *gorm.DB) error {
|
|
rows, err := Status(gdb, plugins)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
tableRows := make([][]string, 0, len(rows))
|
|
for _, row := range rows {
|
|
ids := "(none)"
|
|
if len(row.IDs) > 0 {
|
|
ids = fmt.Sprintf("%d: %s", len(row.IDs), row.IDs[len(row.IDs)-1])
|
|
}
|
|
tableRows = append(tableRows, []string{row.Plugin, row.Table, ids})
|
|
}
|
|
out.Table([]string{"plugin", "table", "applied"}, tableRows)
|
|
return nil
|
|
})
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func withDB(ctx context.Context, app *backpack.App, fn func(*gorm.DB) error) error {
|
|
sqlDB, gdb, err := OpenFromApp(ctx, app)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer sqlDB.Close()
|
|
if err := Publish(app, sqlDB, gdb); err != nil {
|
|
return err
|
|
}
|
|
return fn(gdb)
|
|
}
|