- Updated main.go to initialize email service and include it in the dependency injection container. - Refactored handlers to utilize context in service method calls, improving consistency and error handling. - Introduced new service options for upload, security, and captcha services, enhancing modularity and testability. - Removed unused repository implementations to streamline the codebase. This commit continues the effort to improve the architecture by ensuring all services are properly injected and utilized across the application.
97 lines
2.3 KiB
Go
97 lines
2.3 KiB
Go
package database
|
||
|
||
import (
|
||
"fmt"
|
||
"log"
|
||
"os"
|
||
"time"
|
||
|
||
"carrotskin/pkg/config"
|
||
|
||
"gorm.io/driver/postgres"
|
||
"gorm.io/gorm"
|
||
"gorm.io/gorm/logger"
|
||
)
|
||
|
||
// New 创建新的PostgreSQL数据库连接
|
||
func New(cfg config.DatabaseConfig) (*gorm.DB, error) {
|
||
dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s TimeZone=%s",
|
||
cfg.Host,
|
||
cfg.Port,
|
||
cfg.Username,
|
||
cfg.Password,
|
||
cfg.Database,
|
||
cfg.SSLMode,
|
||
cfg.Timezone,
|
||
)
|
||
|
||
// 配置慢查询监控
|
||
newLogger := logger.New(
|
||
log.New(os.Stdout, "\r\n", log.LstdFlags),
|
||
logger.Config{
|
||
SlowThreshold: 200 * time.Millisecond, // 慢查询阈值:200ms
|
||
LogLevel: logger.Warn, // 只记录警告和错误
|
||
IgnoreRecordNotFoundError: true, // 忽略记录未找到错误
|
||
Colorful: false, // 生产环境禁用彩色
|
||
},
|
||
)
|
||
|
||
// 打开数据库连接
|
||
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
|
||
Logger: newLogger,
|
||
DisableForeignKeyConstraintWhenMigrating: true, // 禁用外键约束
|
||
PrepareStmt: true, // 启用预编译语句缓存
|
||
QueryFields: true, // 明确指定查询字段
|
||
})
|
||
if err != nil {
|
||
return nil, fmt.Errorf("连接PostgreSQL数据库失败: %w", err)
|
||
}
|
||
|
||
// 获取底层SQL数据库实例
|
||
sqlDB, err := db.DB()
|
||
if err != nil {
|
||
return nil, fmt.Errorf("获取数据库实例失败: %w", err)
|
||
}
|
||
|
||
// 优化连接池配置
|
||
maxIdleConns := cfg.MaxIdleConns
|
||
if maxIdleConns <= 0 {
|
||
maxIdleConns = 10
|
||
}
|
||
|
||
maxOpenConns := cfg.MaxOpenConns
|
||
if maxOpenConns <= 0 {
|
||
maxOpenConns = 100
|
||
}
|
||
|
||
connMaxLifetime := cfg.ConnMaxLifetime
|
||
if connMaxLifetime <= 0 {
|
||
connMaxLifetime = 1 * time.Hour
|
||
}
|
||
|
||
sqlDB.SetMaxIdleConns(maxIdleConns)
|
||
sqlDB.SetMaxOpenConns(maxOpenConns)
|
||
sqlDB.SetConnMaxLifetime(connMaxLifetime)
|
||
sqlDB.SetConnMaxIdleTime(10 * time.Minute)
|
||
|
||
// 测试连接
|
||
if err := sqlDB.Ping(); err != nil {
|
||
return nil, fmt.Errorf("数据库连接测试失败: %w", err)
|
||
}
|
||
|
||
return db, nil
|
||
}
|
||
|
||
// GetDSN 获取数据源名称
|
||
func GetDSN(cfg config.DatabaseConfig) string {
|
||
return fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s TimeZone=%s",
|
||
cfg.Host,
|
||
cfg.Port,
|
||
cfg.Username,
|
||
cfg.Password,
|
||
cfg.Database,
|
||
cfg.SSLMode,
|
||
cfg.Timezone,
|
||
)
|
||
}
|