mirror of
https://git.fightbot.fun/hxuanyu/BingPaper.git
synced 2026-02-15 07:19:33 +08:00
优化数据库初始化逻辑,新增配置热更新与自动迁移支持,升级相关依赖
This commit is contained in:
@@ -65,6 +65,16 @@ func Init(webFS embed.FS, configPath string) *gin.Engine {
|
||||
util.Logger.Fatal("Failed to initialize database")
|
||||
}
|
||||
|
||||
// 注册数据库配置变更回调,支持热迁移
|
||||
config.OnDBConfigChange = func(newCfg *config.Config) {
|
||||
util.Logger.Info("Database configuration change detected, initiating migration...")
|
||||
if err := repo.MigrateDataToNewDB(repo.DB, newCfg); err != nil {
|
||||
util.Logger.Error("Automatic data migration failed", zap.Error(err))
|
||||
} else {
|
||||
util.Logger.Info("Automatic data migration finished")
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 初始化存储
|
||||
var s storage.Storage
|
||||
var err error
|
||||
|
||||
@@ -127,6 +127,9 @@ var (
|
||||
GlobalConfig *Config
|
||||
configLock sync.RWMutex
|
||||
v *viper.Viper
|
||||
|
||||
// OnDBConfigChange 当数据库配置发生变更时的回调函数
|
||||
OnDBConfigChange func(newCfg *Config)
|
||||
)
|
||||
|
||||
func Init(configPath string) error {
|
||||
@@ -206,8 +209,19 @@ func Init(configPath string) error {
|
||||
var newCfg Config
|
||||
if err := v.Unmarshal(&newCfg); err == nil {
|
||||
configLock.Lock()
|
||||
oldDBConfig := GlobalConfig.DB
|
||||
GlobalConfig = &newCfg
|
||||
newDBConfig := newCfg.DB
|
||||
configLock.Unlock()
|
||||
|
||||
// 检查数据库配置是否发生变更
|
||||
if oldDBConfig.Type != newDBConfig.Type || oldDBConfig.DSN != newDBConfig.DSN {
|
||||
// 触发数据库迁移逻辑
|
||||
// 这里由于循环依赖问题,我们可能需要通过回调或者一个统一的 Reload 函数来处理
|
||||
if OnDBConfigChange != nil {
|
||||
OnDBConfigChange(&newCfg)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
v.WatchConfig()
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"BingPaper/internal/http/handlers"
|
||||
"BingPaper/internal/http/middleware"
|
||||
|
||||
"github.com/gin-contrib/cors"
|
||||
"github.com/gin-gonic/gin"
|
||||
swaggerFiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
@@ -22,6 +23,14 @@ import (
|
||||
func SetupRouter(webFS embed.FS) *gin.Engine {
|
||||
r := gin.Default()
|
||||
|
||||
// CORS 配置:更宽松的配置以解决 Vue 等前端的预检请求问题
|
||||
corsConfig := cors.DefaultConfig()
|
||||
corsConfig.AllowAllOrigins = true
|
||||
corsConfig.AllowMethods = []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"}
|
||||
corsConfig.AllowHeaders = []string{"Origin", "Content-Length", "Content-Type", "Authorization", "Accept", "X-Requested-With"}
|
||||
corsConfig.AllowCredentials = true
|
||||
r.Use(cors.New(corsConfig))
|
||||
|
||||
// Swagger
|
||||
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
|
||||
|
||||
@@ -76,21 +76,20 @@ func (l *gormLogger) Trace(ctx context.Context, begin time.Time, fc func() (stri
|
||||
}
|
||||
}
|
||||
|
||||
func InitDB() error {
|
||||
cfg := config.GetConfig()
|
||||
var dialector gorm.Dialector
|
||||
|
||||
switch cfg.DB.Type {
|
||||
func GetDialector(dbType, dsn string) (gorm.Dialector, error) {
|
||||
switch dbType {
|
||||
case "mysql":
|
||||
dialector = mysql.Open(cfg.DB.DSN)
|
||||
return mysql.Open(dsn), nil
|
||||
case "postgres":
|
||||
dialector = postgres.Open(cfg.DB.DSN)
|
||||
return postgres.Open(dsn), nil
|
||||
case "sqlite":
|
||||
dialector = sqlite.Open(cfg.DB.DSN)
|
||||
return sqlite.Open(dsn), nil
|
||||
default:
|
||||
return fmt.Errorf("unsupported db type: %s", cfg.DB.Type)
|
||||
return nil, fmt.Errorf("unsupported db type: %s", dbType)
|
||||
}
|
||||
}
|
||||
|
||||
func GetGormConfig(cfg *config.Config) *gorm.Config {
|
||||
gormLogLevel := logger.Info
|
||||
switch cfg.Log.DBLogLevel {
|
||||
case "debug":
|
||||
@@ -105,13 +104,23 @@ func InitDB() error {
|
||||
gormLogLevel = logger.Silent
|
||||
}
|
||||
|
||||
gormConfig := &gorm.Config{
|
||||
return &gorm.Config{
|
||||
Logger: &gormLogger{
|
||||
ZapLogger: util.DBLogger,
|
||||
LogLevel: gormLogLevel,
|
||||
},
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
}
|
||||
}
|
||||
|
||||
func InitDB() error {
|
||||
cfg := config.GetConfig()
|
||||
dialector, err := GetDialector(cfg.DB.Type, cfg.DB.DSN)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gormConfig := GetGormConfig(cfg)
|
||||
|
||||
db, err := gorm.Open(dialector, gormConfig)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user