94 lines
2.4 KiB
Go
94 lines
2.4 KiB
Go
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
|
||
}
|