From 8c075194e557332c25ed45a49882cedd6f65d150 Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Thu, 23 Apr 2026 16:58:01 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=90=8E=E4=BB=A3=E7=A0=81=E8=B4=A8=E9=87=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修正 Makefile 迁移目录路径(sqlite3 → sqlite) - 统一 database.go 日志风格(log.Printf → zapLogger) - 修复 config.go validator 标签大小写 - 修复 database_test.go 测试使用 nil logger - 移除未使用的 log 导入 --- Makefile | 6 +-- backend/cmd/desktop/main.go | 1 - backend/internal/config/config.go | 10 ++--- backend/internal/database/database.go | 51 +++++++++++++++------- backend/internal/database/database_test.go | 7 ++- go.work.sum | 2 + 6 files changed, 50 insertions(+), 27 deletions(-) diff --git a/Makefile b/Makefile index 04da5e8..a1d3acb 100644 --- a/Makefile +++ b/Makefile @@ -68,15 +68,15 @@ backend-generate: backend-db-up: @echo "Running database migration up..." - cd backend && goose -dir migrations/sqlite3 sqlite3 "$(DB_PATH)" up + cd backend && goose -dir migrations/sqlite sqlite3 "$(DB_PATH)" up backend-db-down: @echo "Running database migration down..." - cd backend && goose -dir migrations/sqlite3 sqlite3 "$(DB_PATH)" down + cd backend && goose -dir migrations/sqlite sqlite3 "$(DB_PATH)" down backend-db-status: @echo "Checking database migration status..." - cd backend && goose -dir migrations/sqlite3 sqlite3 "$(DB_PATH)" status + cd backend && goose -dir migrations/sqlite sqlite3 "$(DB_PATH)" status backend-db-create: @read -p "Migration name: " name; \ diff --git a/backend/cmd/desktop/main.go b/backend/cmd/desktop/main.go index aabd816..e486639 100644 --- a/backend/cmd/desktop/main.go +++ b/backend/cmd/desktop/main.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "io/fs" - "log" "net" "net/http" "os" diff --git a/backend/internal/config/config.go b/backend/internal/config/config.go index 391535d..773590f 100644 --- a/backend/internal/config/config.go +++ b/backend/internal/config/config.go @@ -33,12 +33,12 @@ type ServerConfig struct { // DatabaseConfig 数据库配置 type DatabaseConfig struct { Driver string `yaml:"driver" mapstructure:"driver" validate:"required,oneof=sqlite mysql"` - Path string `yaml:"path" mapstructure:"path" validate:"required_if=Driver sqlite"` - Host string `yaml:"host" mapstructure:"host" validate:"required_if=Driver mysql"` - Port int `yaml:"port" mapstructure:"port" validate:"required_if=Driver mysql,min=1,max=65535"` - User string `yaml:"user" mapstructure:"user" validate:"required_if=Driver mysql"` + Path string `yaml:"path" mapstructure:"path" validate:"required_if=driver sqlite"` + Host string `yaml:"host" mapstructure:"host" validate:"required_if=driver mysql"` + Port int `yaml:"port" mapstructure:"port" validate:"required_if=driver mysql,min=1,max=65535"` + User string `yaml:"user" mapstructure:"user" validate:"required_if=driver mysql"` Password string `yaml:"password" mapstructure:"password"` - DBName string `yaml:"dbname" mapstructure:"dbname" validate:"required_if=Driver mysql"` + DBName string `yaml:"dbname" mapstructure:"dbname" validate:"required_if=driver mysql"` MaxIdleConns int `yaml:"max_idle_conns" mapstructure:"max_idle_conns" validate:"required,min=1"` MaxOpenConns int `yaml:"max_open_conns" mapstructure:"max_open_conns" validate:"required,min=1"` ConnMaxLifetime time.Duration `yaml:"conn_max_lifetime" mapstructure:"conn_max_lifetime" validate:"required"` diff --git a/backend/internal/database/database.go b/backend/internal/database/database.go index 76661a5..abe30ca 100644 --- a/backend/internal/database/database.go +++ b/backend/internal/database/database.go @@ -2,7 +2,6 @@ package database import ( "fmt" - "log" "os" "path/filepath" "runtime" @@ -18,16 +17,16 @@ import ( ) func Init(cfg *config.DatabaseConfig, zapLogger *zap.Logger) (*gorm.DB, error) { - db, err := initDB(cfg) + db, err := initDB(cfg, zapLogger) if err != nil { return nil, fmt.Errorf("初始化数据库失败: %w", err) } - if err := runMigrations(db, cfg.Driver); err != nil { + if err := runMigrations(db, cfg.Driver, zapLogger); err != nil { return nil, fmt.Errorf("数据库迁移失败: %w", err) } - configurePool(db, cfg) + configurePool(db, cfg, zapLogger) return db, nil } @@ -40,7 +39,7 @@ func Close(db *gorm.DB) { sqlDB.Close() } -func initDB(cfg *config.DatabaseConfig) (*gorm.DB, error) { +func initDB(cfg *config.DatabaseConfig, zapLogger *zap.Logger) (*gorm.DB, error) { gormConfig := &gorm.Config{ Logger: logger.Default.LogMode(logger.Info), } @@ -49,27 +48,31 @@ func initDB(cfg *config.DatabaseConfig) (*gorm.DB, error) { case "mysql": dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=true&loc=Local", cfg.User, cfg.Password, cfg.Host, cfg.Port, cfg.DBName) + if zapLogger != nil { + zapLogger.Info("连接 MySQL 数据库", + zap.String("host", cfg.Host), + zap.Int("port", cfg.Port), + zap.String("database", cfg.DBName)) + } return gorm.Open(mysql.Open(dsn), gormConfig) default: dbDir := filepath.Dir(cfg.Path) if err := os.MkdirAll(dbDir, 0755); err != nil { return nil, fmt.Errorf("创建数据库目录失败: %w", err) } + if zapLogger != nil { + zapLogger.Info("连接 SQLite 数据库", zap.String("path", cfg.Path)) + } return gorm.Open(sqlite.Open(cfg.Path), gormConfig) } } -func runMigrations(db *gorm.DB, driver string) error { +func runMigrations(db *gorm.DB, driver string, zapLogger *zap.Logger) error { sqlDB, err := db.DB() if err != nil { return err } - migrationsDir := getMigrationsDir(driver) - if _, err := os.Stat(migrationsDir); os.IsNotExist(err) { - return fmt.Errorf("迁移目录不存在: %s", migrationsDir) - } - gooseDialect := "sqlite3" migrationsSubDir := "sqlite" if driver == "mysql" { @@ -77,19 +80,31 @@ func runMigrations(db *gorm.DB, driver string) error { migrationsSubDir = "mysql" } + migrationsDir := getMigrationsDir(driver) + if _, err := os.Stat(migrationsDir); os.IsNotExist(err) { + return fmt.Errorf("迁移目录不存在: %s", migrationsDir) + } + + if zapLogger != nil { + zapLogger.Info("执行数据库迁移", + zap.String("dialect", gooseDialect), + zap.String("dir", migrationsSubDir)) + } + goose.SetDialect(gooseDialect) if err := goose.Up(sqlDB, migrationsDir); err != nil { return err } - log.Printf("使用 %s 方言执行迁移,目录: %s", gooseDialect, migrationsSubDir) return nil } -func configurePool(db *gorm.DB, cfg *config.DatabaseConfig) { +func configurePool(db *gorm.DB, cfg *config.DatabaseConfig, zapLogger *zap.Logger) { if cfg.Driver == "sqlite" { if err := db.Exec("PRAGMA journal_mode=WAL").Error; err != nil { - log.Printf("警告: 启用 WAL 模式失败: %v", err) + if zapLogger != nil { + zapLogger.Warn("启用 WAL 模式失败", zap.Error(err)) + } } } @@ -101,8 +116,12 @@ func configurePool(db *gorm.DB, cfg *config.DatabaseConfig) { sqlDB.SetMaxOpenConns(cfg.MaxOpenConns) sqlDB.SetConnMaxLifetime(cfg.ConnMaxLifetime) - log.Printf("数据库连接池配置: MaxIdle=%d, MaxOpen=%d, MaxLifetime=%v", - cfg.MaxIdleConns, cfg.MaxOpenConns, cfg.ConnMaxLifetime) + if zapLogger != nil { + zapLogger.Info("数据库连接池配置", + zap.Int("max_idle_conns", cfg.MaxIdleConns), + zap.Int("max_open_conns", cfg.MaxOpenConns), + zap.Duration("conn_max_lifetime", cfg.ConnMaxLifetime)) + } } func getMigrationsDir(driver string) string { diff --git a/backend/internal/database/database_test.go b/backend/internal/database/database_test.go index ddb5669..e96a9e2 100644 --- a/backend/internal/database/database_test.go +++ b/backend/internal/database/database_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.uber.org/zap" "nex/backend/internal/config" ) @@ -20,7 +21,8 @@ func TestInit_SQLite(t *testing.T) { ConnMaxLifetime: 0, } - db, err := Init(cfg, nil) + zapLogger := zap.NewNop() + db, err := Init(cfg, zapLogger) require.NoError(t, err) require.NotNil(t, db) defer Close(db) @@ -40,7 +42,8 @@ func TestClose(t *testing.T) { ConnMaxLifetime: 0, } - db, err := Init(cfg, nil) + zapLogger := zap.NewNop() + db, err := Init(cfg, zapLogger) require.NoError(t, err) require.NotNil(t, db) diff --git a/go.work.sum b/go.work.sum index 6d83183..d66ce50 100644 --- a/go.work.sum +++ b/go.work.sum @@ -4,6 +4,7 @@ cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQ cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc= cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= cloud.google.com/go/longrunning v0.5.7/go.mod h1:8GClkudohy1Fxm3owmBGid8W0pSgodEMwEAztp38Xng= +filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo= filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc= github.com/ClickHouse/ch-go v0.71.0/go.mod h1:NwbNc+7jaqfY58dmdDUbG4Jl22vThgx1cYjBw0vtgXw= github.com/ClickHouse/clickhouse-go/v2 v2.43.0/go.mod h1:o6jf7JM/zveWC/PP277BLxjHy5KjnGX/jfljhM4s34g= @@ -25,6 +26,7 @@ github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6v github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=