156 lines
3.5 KiB
Go
156 lines
3.5 KiB
Go
package db
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
_ "github.com/go-sql-driver/mysql"
|
|
"log/slog"
|
|
"os"
|
|
"path/filepath"
|
|
"slgserver/config"
|
|
"time"
|
|
"xorm.io/xorm"
|
|
"xorm.io/xorm/log"
|
|
)
|
|
|
|
var MasterDB *xorm.Engine
|
|
|
|
var logFileHandle *os.File
|
|
|
|
var (
|
|
ConnectDBErr = errors.New("connect db error")
|
|
UseDBErr = errors.New("use db error")
|
|
)
|
|
|
|
// TestDB 测试数据库
|
|
func TestDB() error {
|
|
mysqlConfig, err := config.GetSection("mysql")
|
|
if err != nil {
|
|
slog.Error("get mysql config error", "error", err)
|
|
panic(err)
|
|
}
|
|
|
|
tmpDns := fmt.Sprintf("%s:%s@tcp(%s:%s)/?charset=%s&parseTime=True&loc=Local",
|
|
mysqlConfig["user"],
|
|
mysqlConfig["password"],
|
|
mysqlConfig["host"],
|
|
mysqlConfig["port"],
|
|
mysqlConfig["charset"])
|
|
egnine, err := xorm.NewEngine("mysql", tmpDns)
|
|
if err != nil {
|
|
slog.Error("new engine error", "error", err)
|
|
panic(err)
|
|
}
|
|
defer egnine.Close()
|
|
|
|
// 测试数据库连接是否 OK
|
|
if err = egnine.Ping(); err != nil {
|
|
slog.Error("ping db error", "error", err)
|
|
return ConnectDBErr
|
|
}
|
|
|
|
_, err = egnine.Exec("use " + mysqlConfig["dbname"])
|
|
if err != nil {
|
|
slog.Error("use db error", "error", err)
|
|
// 使用参数化查询避免SQL注入风险
|
|
createDBQuery := fmt.Sprintf("CREATE DATABASE `%s` DEFAULT CHARACTER SET %s", mysqlConfig["dbname"], mysqlConfig["charset"])
|
|
_, err = egnine.Exec(createDBQuery)
|
|
if err != nil {
|
|
slog.Error("create database error", "error", err)
|
|
|
|
return UseDBErr
|
|
}
|
|
|
|
slog.Info("create database successfully")
|
|
}
|
|
|
|
// 初始化 MasterDB
|
|
return Init()
|
|
}
|
|
|
|
func Init() error {
|
|
mysqlConfig, err := config.GetSection("mysql")
|
|
if err != nil {
|
|
slog.Error("get mysql config error", "error", err)
|
|
return err
|
|
}
|
|
|
|
// 启动时就打开数据库连接
|
|
if err = initEngine(mysqlConfig); err != nil {
|
|
slog.Error("mysql is not open", "error", err)
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func fillDns(mysqlConfig map[string]string) string {
|
|
return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=True&loc=Local",
|
|
mysqlConfig["user"],
|
|
mysqlConfig["password"],
|
|
mysqlConfig["host"],
|
|
mysqlConfig["port"],
|
|
mysqlConfig["dbname"],
|
|
mysqlConfig["charset"])
|
|
}
|
|
|
|
func initEngine(mysqlConfig map[string]string) error {
|
|
|
|
var err error
|
|
dns := fillDns(mysqlConfig)
|
|
|
|
MasterDB, err = xorm.NewEngine("mysql", dns)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 数据库连接池配置,根据实际负载调整
|
|
maxIdle := config.GetInt("mysql.max_idle", 10) // 默认值从2提升到10
|
|
maxConn := config.GetInt("mysql.max_conn", 100) // 默认值从10提升到100
|
|
|
|
MasterDB.SetMaxIdleConns(maxIdle)
|
|
MasterDB.SetMaxOpenConns(maxConn)
|
|
|
|
// 设置连接最大生存时间,避免长时间连接导致的问题
|
|
MasterDB.SetConnMaxLifetime(time.Hour)
|
|
|
|
showSQL := config.GetBool("xorm.show_sql", false)
|
|
logLevel := config.GetInt("xorm.log_level", 1)
|
|
logFile := config.GetPath("xorm.log_file", "")
|
|
|
|
if logFile != "" {
|
|
if logFileHandle != nil {
|
|
logFileHandle.Close()
|
|
}
|
|
// 确保日志文件目录存在
|
|
if err := os.MkdirAll(filepath.Dir(logFile), 0755); err != nil {
|
|
return fmt.Errorf("failed to create log directory: %w", err)
|
|
}
|
|
f, err := os.OpenFile(logFile, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
logFileHandle = f
|
|
MasterDB.SetLogger(log.NewSimpleLogger(f))
|
|
}
|
|
|
|
MasterDB.SetLogLevel(log.LogLevel(logLevel))
|
|
MasterDB.ShowSQL(showSQL)
|
|
|
|
return nil
|
|
}
|
|
|
|
func StdMasterDB() *sql.DB {
|
|
return MasterDB.DB().DB
|
|
}
|
|
|
|
func Close() {
|
|
if MasterDB != nil {
|
|
MasterDB.Close()
|
|
}
|
|
if logFileHandle != nil {
|
|
logFileHandle.Close()
|
|
}
|
|
}
|