Cybersecurity-Projects/PROJECTS/advanced/honeypot-network/internal/cli/migrate.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)
}