Files
cmroubao/backend-api/cmd/migrate/main.go
T

80 lines
1.7 KiB
Go
Raw Normal View History

package main
import (
"context"
"errors"
"fmt"
"log"
"os"
"time"
"cmroubao/backend-api/internal/config"
"cmroubao/backend-api/internal/platform/database"
"cmroubao/backend-api/internal/platform/migration"
)
func main() {
if err := run(os.Args[1:]); err != nil {
log.Printf("migration command failed: %v", err)
os.Exit(1)
}
}
func run(arguments []string) error {
if len(arguments) != 1 {
return errors.New("usage: migrate <up|down|status>")
}
command := arguments[0]
if command != "up" && command != "down" && command != "status" {
return errors.New("migration command must be up, down, or status")
}
databasePath, err := config.LoadDatabasePath(os.LookupEnv)
if err != nil {
return err
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
db, err := database.Open(ctx, databasePath)
if err != nil {
return errors.New("database startup failed")
}
defer func() {
if err := db.Close(); err != nil {
log.Print("database close failed")
}
}()
runner, err := migration.New(db)
if err != nil {
return errors.New("migration setup failed")
}
switch command {
case "up":
count, err := runner.Up(ctx)
if err != nil {
return errors.New("migration up failed")
}
fmt.Printf("applied=%d\n", count)
case "down":
if err := runner.Down(ctx); err != nil {
return errors.New("migration down failed")
}
fmt.Println("rolled_back=1")
case "status":
statuses, err := runner.Status(ctx)
if err != nil {
return errors.New("migration status failed")
}
for _, status := range statuses {
state := "pending"
if status.Applied {
state = "applied"
}
fmt.Printf("version=%d state=%s\n", status.Version, state)
}
}
return nil
}