From 3ac230cdf795163bd6084d012286f924252f9f80 Mon Sep 17 00:00:00 2001 From: engigu Date: Mon, 16 Mar 2026 08:33:48 +0800 Subject: [PATCH] feat: add dsn support #55 --- configs/config.example.ini | 3 +++ docs/guide/configuration.md | 4 ++++ internal/bootstrap/bootstrap.go | 1 + internal/database/database.go | 8 ++++++-- internal/services/config_service.go | 6 ++++-- 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/configs/config.example.ini b/configs/config.example.ini index 083660e..98304d0 100644 --- a/configs/config.example.ini +++ b/configs/config.example.ini @@ -22,6 +22,9 @@ password = dbname = baihu # 数据库文件路径 (仅 sqlite) path = data/baihu.db +# 数据库 DSN (仅 mysql/mariadb, 如果设置则优先使用。注意:需同时将 type 设置为 mysql) +# 例如: user:password@unix(/var/run/mysqld/mysqld.sock)/dbname?charset=utf8mb4&parseTime=True&loc=Local +dsn = # 表前缀 table_prefix = baihu_ diff --git a/docs/guide/configuration.md b/docs/guide/configuration.md index 7c14c20..feee49c 100644 --- a/docs/guide/configuration.md +++ b/docs/guide/configuration.md @@ -20,6 +20,7 @@ | `BH_DB_PASSWORD` | database.password | 数据库密码 | - | | `BH_DB_NAME` | database.dbname | 数据库库名 | baihu | | `BH_DB_PATH` | database.path | SQLite 物理文件存储路径 | ./data/baihu.db | +| `BH_DB_DSN` | database.dsn | 数据库 DSN (仅 mysql, 优先级高。**需同时设置 type=mysql**) | - | | `BH_DB_TABLE_PREFIX` | database.table_prefix | 数据库表前缀 | baihu_ | --- @@ -45,6 +46,9 @@ url_prefix = /baihu [database] type = sqlite path = /app/data/baihu.db +# mysql 连接示例 (Unix Socket): +# 注意:使用 dsn 时,type 必须设为 mysql +# dsn = user:password@unix(/var/run/mysqld/mysqld.sock)/dbname?charset=utf8mb4&parseTime=True&loc=Local table_prefix = baihu_ ``` diff --git a/internal/bootstrap/bootstrap.go b/internal/bootstrap/bootstrap.go index 9594af6..63b7155 100644 --- a/internal/bootstrap/bootstrap.go +++ b/internal/bootstrap/bootstrap.go @@ -82,6 +82,7 @@ func (a *App) initDatabase() { Password: a.Config.Database.Password, DBName: a.Config.Database.DBName, Path: a.Config.Database.Path, + DSN: a.Config.Database.DSN, } if err := database.Init(dbCfg); err != nil { diff --git a/internal/database/database.go b/internal/database/database.go index c810445..fc71c09 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -25,6 +25,7 @@ type Config struct { Password string DBName string Path string // for sqlite + DSN string // for mysql/mariadb unix socket or custom dsn } func Init(cfg *Config) error { @@ -40,8 +41,11 @@ func Init(cfg *Config) error { case "sqlite": dialector = sqlite.Open(cfg.Path + "?_busy_timeout=5000") case "mysql": - dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Asia%%2FShanghai", - cfg.User, cfg.Password, cfg.Host, cfg.Port, cfg.DBName) + dsn := cfg.DSN + if dsn == "" { + dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Asia%%2FShanghai", + cfg.User, cfg.Password, cfg.Host, cfg.Port, cfg.DBName) + } dialector = mysql.Open(dsn) case "postgres": dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable TimeZone=Asia/Shanghai", diff --git a/internal/services/config_service.go b/internal/services/config_service.go index 66c5709..6827bf2 100644 --- a/internal/services/config_service.go +++ b/internal/services/config_service.go @@ -25,6 +25,7 @@ type DatabaseConfig struct { Password string `ini:"password"` DBName string `ini:"dbname"` Path string `ini:"path"` + DSN string `ini:"dsn"` TablePrefix string `ini:"table_prefix"` } @@ -127,8 +128,8 @@ func LoadConfig(path string) (*AppConfig, error) { if Config.Server.URLPrefix != "" { logger.Infof("[Config] URL前缀: %s", Config.Server.URLPrefix) } - logger.Infof("[Config] 数据库: type=%s, host=%s, port=%d, dbname=%s", - Config.Database.Type, Config.Database.Host, Config.Database.Port, Config.Database.DBName) + logger.Infof("[Config] 数据库: type=%s, host=%s, port=%d, dbname=%s, dsn=%v", + Config.Database.Type, Config.Database.Host, Config.Database.Port, Config.Database.DBName, Config.Database.DSN != "") return Config, nil } @@ -149,6 +150,7 @@ func applyEnvOverrides() { getEnvStr("BH_DB_PASSWORD", &Config.Database.Password) getEnvStr("BH_DB_NAME", &Config.Database.DBName) getEnvStr("BH_DB_PATH", &Config.Database.Path) + getEnvStr("BH_DB_DSN", &Config.Database.DSN) getEnvStr("BH_DB_TABLE_PREFIX", &Config.Database.TablePrefix) // Security