refactor: 移除全局单例、修复分层违规、统一错误与响应
Some checks failed
Build / build (push) Successful in 7m52s
Build / build-docker (push) Has been cancelled

This commit is contained in:
lafay
2026-06-15 16:40:36 +08:00
parent d9de39a0a3
commit 7d1c78f965
55 changed files with 593 additions and 1744 deletions

View File

@@ -2,74 +2,25 @@ package database
import (
"carrotskin/internal/model"
"carrotskin/pkg/config"
"fmt"
"sync"
"go.uber.org/zap"
"gorm.io/gorm"
)
var (
// dbInstance 全局数据库实例(使用 *DB 封装)
dbInstance *DB
// once 确保只初始化一次
once sync.Once
// initError 初始化错误
initError error
)
// Init 初始化数据库连接(线程安全,只会执行一次)
func Init(cfg config.DatabaseConfig, logger *zap.Logger) error {
once.Do(func() {
dbInstance, initError = New(cfg)
if initError != nil {
logger.Error("数据库初始化失败", zap.Error(initError))
return
}
logger.Info("数据库连接成功")
})
return initError
}
// GetDB 获取数据库实例(线程安全)
// 返回 *gorm.DB 以保持向后兼容
func GetDB() (*gorm.DB, error) {
if dbInstance == nil {
return nil, fmt.Errorf("数据库未初始化,请先调用 database.Init()")
}
return dbInstance.DB, nil
}
// GetDBWrapper 获取数据库封装实例(包含连接池统计功能)
func GetDBWrapper() (*DB, error) {
if dbInstance == nil {
return nil, fmt.Errorf("数据库未初始化,请先调用 database.Init()")
}
return dbInstance, nil
}
// MustGetDB 获取数据库实例如果未初始化则panic
// 返回 *gorm.DB 以保持向后兼容
func MustGetDB() *gorm.DB {
db, err := GetDB()
if err != nil {
panic(err)
}
return db
}
// AutoMigrate 自动迁移数据库表结构
func AutoMigrate(logger *zap.Logger) error {
db, err := GetDB()
if err != nil {
return fmt.Errorf("获取数据库实例失败: %w", err)
}
// 本文件原包含基于 sync.Once 的全局单例Init/GetDB/MustGetDB/GetDBWrapper
//
// 在 DI 迁移阶段4全局单例已被移除。数据库连接由 fx.Provide 构造
// (见 internal/app/infra_module.go 的 provideDatabase通过构造函数参数
// 注入 *database.DB 与 *gorm.DB 到各消费者。
//
// 数据库构造逻辑见 postgres.go 的 New()。
// AutoMigrateWithDB 使用指定的 *gorm.DB 执行表结构迁移(供 DI 使用)。
// 注意表的创建顺序:先创建被引用的表,再创建引用表。
func AutoMigrateWithDB(db *gorm.DB, logger *zap.Logger) error {
logger.Info("开始执行数据库迁移...")
// 迁移所有表 - 注意顺序:先创建被引用的表,再创建引用表
// 使用分批迁移,避免某些表的问题影响其他表
tables := []interface{}{
// 用户相关表(先创建,因为其他表可能引用它)
&model.User{},
@@ -97,7 +48,6 @@ func AutoMigrate(logger *zap.Logger) error {
&model.CasbinRule{},
}
// 批量迁移表
if err := db.AutoMigrate(tables...); err != nil {
logger.Error("数据库迁移失败", zap.Error(err))
return fmt.Errorf("数据库迁移失败: %w", err)
@@ -106,12 +56,3 @@ func AutoMigrate(logger *zap.Logger) error {
logger.Info("数据库迁移完成")
return nil
}
// Close 关闭数据库连接
func Close() error {
if dbInstance == nil {
return nil
}
return dbInstance.Close()
}