Files
team-api/internal/cmd/cmd_migrate.go
T

94 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package cmd
import (
"context"
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gcmd"
"github.com/pressly/goose/v3"
"github.com/qianfree/team-api/migrations"
)
var migrateCmd = gcmd.Command{
Name: "migrate",
Usage: "migrate [up|down|status]",
Brief: "执行数据库迁移",
Description: `数据库迁移管理命令。
migrate 执行所有待迁移脚本(等同于 migrate up)
migrate up 执行所有待迁移脚本
migrate down 回滚上一次迁移
migrate status 查看迁移状态`,
Func: func(ctx context.Context, parser *gcmd.Parser) error {
action := "up"
if args := parser.GetArgAll(); len(args) > 2 {
action = args[2]
}
return runMigrate(ctx, action)
},
}
func init() {
err := Main.AddCommand(&migrateCmd)
if err != nil {
panic(fmt.Sprintf("注册 migrate 命令失败: %v", err))
}
}
func runMigrate(ctx context.Context, action string) error {
db, err := g.DB().Master()
if err != nil {
return fmt.Errorf("获取数据库连接失败: %w", err)
}
goose.SetBaseFS(migrations.FS)
if err := goose.SetDialect("postgres"); err != nil {
return fmt.Errorf("设置数据库方言失败: %w", err)
}
switch action {
case "up":
return goose.UpContext(ctx, db, ".")
case "down":
return goose.DownContext(ctx, db, ".")
case "status":
return goose.StatusContext(ctx, db, ".")
default:
return fmt.Errorf("未知的迁移操作: %s(可选: up, down, status)", action)
}
}
// runAutoMigrate is called during application startup to ensure the database
// schema is up to date before serving requests.
func runAutoMigrate(ctx context.Context) error {
g.Log().Info(ctx, "执行数据库自动迁移...")
db, err := g.DB().Master()
if err != nil {
return fmt.Errorf("获取数据库连接失败: %w", err)
}
goose.SetBaseFS(migrations.FS)
if err := goose.SetDialect("postgres"); err != nil {
return fmt.Errorf("设置数据库方言失败: %w", err)
}
if err := goose.UpContext(ctx, db, "."); err != nil {
return fmt.Errorf("数据库迁移失败: %w", err)
}
g.Log().Info(ctx, "数据库迁移完成")
return nil
}
// checkRedis verifies Redis connectivity at startup with a PING command.
// Returns error if Redis is unreachable, causing the program to exit (FATA).
func checkRedis(ctx context.Context) error {
_, err := g.Redis().Do(ctx, "PING")
if err != nil {
return fmt.Errorf("Redis PING 失败: %w", err)
}
return nil
}