Files
agentic-coding-workflow/internal/infra/db/migrate.go
T

46 lines
1.4 KiB
Go

// Package db 提供数据库相关的基础设施工具,包括 golang-migrate 迁移运行器。
package db
import (
"context"
"errors"
"fmt"
"github.com/golang-migrate/migrate/v4"
// 注册 postgres 数据库驱动(database://postgres)。
_ "github.com/golang-migrate/migrate/v4/database/postgres"
// 注册 file:// 迁移源驱动。
_ "github.com/golang-migrate/migrate/v4/source/file"
)
// Migrate 跑指定路径下的迁移到最新版本。ctx 取消可让本函数提前返回 ctx.Err(),
// 但底层 golang-migrate 不接 ctx,已经 in-flight 的 Up() 会继续在后台 goroutine
// 中执行直到自然完成(或外部 statement_timeout 触发)。
// migrationsPath 形如 "file://migrations",dsn 为 postgres 连接串。
// 当无新迁移可应用时(migrate.ErrNoChange)视为成功,返回 nil。
func Migrate(ctx context.Context, dsn, migrationsPath string) error {
m, err := migrate.New(migrationsPath, dsn)
if err != nil {
return fmt.Errorf("init migrate: %w", err)
}
errCh := make(chan error, 1)
go func() {
if err := m.Up(); err != nil && !errors.Is(err, migrate.ErrNoChange) {
errCh <- err
return
}
errCh <- nil
}()
select {
case err := <-errCh:
_, _ = m.Close()
if err != nil {
return fmt.Errorf("migrate up: %w", err)
}
return nil
case <-ctx.Done():
// 注意:m.Close 不能在这里调,会与正在跑的 Up() 竞态。让 goroutine 自然结束。
return ctx.Err()
}
}