94 lines
1.9 KiB
Go
94 lines
1.9 KiB
Go
/*
|
|
©AngelaMos | 2026
|
|
migrate.go
|
|
|
|
Database migration subcommands using goose
|
|
|
|
Provides up, down, and status subcommands to manage the PostgreSQL
|
|
schema lifecycle. Migrations are loaded from the migrations directory
|
|
specified in the configuration file.
|
|
*/
|
|
|
|
package cli
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
|
|
_ "github.com/jackc/pgx/v5/stdlib"
|
|
"github.com/pressly/goose/v3"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
func newMigrateCmd() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "migrate",
|
|
Short: "Run database migrations",
|
|
}
|
|
|
|
cmd.AddCommand(
|
|
newMigrateUpCmd(),
|
|
newMigrateDownCmd(),
|
|
newMigrateStatusCmd(),
|
|
)
|
|
|
|
return cmd
|
|
}
|
|
|
|
func newMigrateUpCmd() *cobra.Command {
|
|
return &cobra.Command{
|
|
Use: "up",
|
|
Short: "Apply all pending migrations",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
return withDB(func(db *sql.DB, dir string) error {
|
|
return goose.Up(db, dir)
|
|
})
|
|
},
|
|
}
|
|
}
|
|
|
|
func newMigrateDownCmd() *cobra.Command {
|
|
return &cobra.Command{
|
|
Use: "down",
|
|
Short: "Roll back the last migration",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
return withDB(func(db *sql.DB, dir string) error {
|
|
return goose.Down(db, dir)
|
|
})
|
|
},
|
|
}
|
|
}
|
|
|
|
func newMigrateStatusCmd() *cobra.Command {
|
|
return &cobra.Command{
|
|
Use: "status",
|
|
Short: "Show migration status",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
return withDB(func(db *sql.DB, dir string) error {
|
|
return goose.Status(db, dir)
|
|
})
|
|
},
|
|
}
|
|
}
|
|
|
|
func withDB(
|
|
fn func(db *sql.DB, dir string) error,
|
|
) error {
|
|
cfg, err := loadConfig()
|
|
if err != nil {
|
|
return fmt.Errorf("loading config: %w", err)
|
|
}
|
|
|
|
db, err := sql.Open("pgx", cfg.Database.DSN)
|
|
if err != nil {
|
|
return fmt.Errorf("connecting to database: %w", err)
|
|
}
|
|
defer func() { _ = db.Close() }()
|
|
|
|
if err := goose.SetDialect("postgres"); err != nil {
|
|
return fmt.Errorf("setting dialect: %w", err)
|
|
}
|
|
|
|
return fn(db, cfg.Database.MigrationsPath)
|
|
}
|