From e1575e3d973571e39c90ea1e007ea2c327a5767a Mon Sep 17 00:00:00 2001 From: Tomas Dvorak Date: Sat, 19 Sep 2026 10:02:21 +0200 Subject: [PATCH] fix(migrator): honor DatabaseURL connection string in v3 migrator The v3->v4 migrator built its DSN from component fields only, ignoring DatabaseURL - so configs that set only a connection string (required for postgres unix sockets, e.g. "host=/var/run/postgresql dbname=...") fell back to a host/port DSN and failed to connect. The migrator now reads DatabaseURL and passes it to gorm verbatim, matching the main client. Closes #42. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- application/migrator/conf/conf.go | 1 + application/migrator/model/init.go | 67 +++++++++++++++++------------- 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/application/migrator/conf/conf.go b/application/migrator/conf/conf.go index 45d059d7..1fc7d874 100644 --- a/application/migrator/conf/conf.go +++ b/application/migrator/conf/conf.go @@ -18,6 +18,7 @@ type database struct { Port int Charset string UnixSocket bool + DatabaseURL string } // system 系统通用配置 diff --git a/application/migrator/model/init.go b/application/migrator/model/init.go index 1e2aca0d..17e34c9e 100644 --- a/application/migrator/model/init.go +++ b/application/migrator/model/init.go @@ -34,36 +34,47 @@ func Init() error { confDBType = "mysql" } - switch confDBType { - case "UNSET", "sqlite": - // 未指定数据库或者明确指定为 sqlite 时,使用 SQLite 数据库 - db, err = gorm.Open("sqlite3", util.RelativePath(conf.DatabaseConfig.DBFile)) - case "postgres": - db, err = gorm.Open(confDBType, fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=disable", - conf.DatabaseConfig.Host, - conf.DatabaseConfig.User, - conf.DatabaseConfig.Password, - conf.DatabaseConfig.Name, - conf.DatabaseConfig.Port)) - case "mysql", "mssql": - var host string - if conf.DatabaseConfig.UnixSocket { - host = fmt.Sprintf("unix(%s)", - conf.DatabaseConfig.Host) - } else { - host = fmt.Sprintf("(%s:%d)", + // A full connection string overrides component fields - required for + // postgres unix sockets ("host=/var/run/postgresql dbname=..."), which + // the component fields cannot express. + if conf.DatabaseConfig.DatabaseURL != "" { + dialect := confDBType + if dialect == "UNSET" || dialect == "sqlite" { + dialect = "sqlite3" + } + db, err = gorm.Open(dialect, conf.DatabaseConfig.DatabaseURL) + } else { + switch confDBType { + case "UNSET", "sqlite": + // 未指定数据库或者明确指定为 sqlite 时,使用 SQLite 数据库 + db, err = gorm.Open("sqlite3", util.RelativePath(conf.DatabaseConfig.DBFile)) + case "postgres": + db, err = gorm.Open(confDBType, fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=disable", conf.DatabaseConfig.Host, - conf.DatabaseConfig.Port) + conf.DatabaseConfig.User, + conf.DatabaseConfig.Password, + conf.DatabaseConfig.Name, + conf.DatabaseConfig.Port)) + case "mysql", "mssql": + var host string + if conf.DatabaseConfig.UnixSocket { + host = fmt.Sprintf("unix(%s)", + conf.DatabaseConfig.Host) + } else { + host = fmt.Sprintf("(%s:%d)", + conf.DatabaseConfig.Host, + conf.DatabaseConfig.Port) + } + + db, err = gorm.Open(confDBType, fmt.Sprintf("%s:%s@%s/%s?charset=%s&parseTime=True&loc=Local", + conf.DatabaseConfig.User, + conf.DatabaseConfig.Password, + host, + conf.DatabaseConfig.Name, + conf.DatabaseConfig.Charset)) + default: + return fmt.Errorf("unsupported database type %q", confDBType) } - - db, err = gorm.Open(confDBType, fmt.Sprintf("%s:%s@%s/%s?charset=%s&parseTime=True&loc=Local", - conf.DatabaseConfig.User, - conf.DatabaseConfig.Password, - host, - conf.DatabaseConfig.Name, - conf.DatabaseConfig.Charset)) - default: - return fmt.Errorf("unsupported database type %q", confDBType) } //db.SetLogger(util.Log())