diff --git a/common/config.go b/common/config.go index e6f0f1367f5559012a5dfc99e2f3675f6036e16c..f933d2729286930605d935716d794003492085c6 100644 --- a/common/config.go +++ b/common/config.go @@ -29,7 +29,9 @@ import ( "regexp" "runtime" "strings" + "time" + "github.com/go-sql-driver/mysql" "gopkg.in/yaml.v2" ) @@ -138,20 +140,8 @@ type Configuration struct { // Config 默认设置 var Config = &Configuration{ - OnlineDSN: &Dsn{ - Net: "tcp", - Schema: "information_schema", - Charset: "utf8mb4", - Disable: true, - Version: 99999, - }, - TestDSN: &Dsn{ - Net: "tcp", - Schema: "information_schema", - Charset: "utf8mb4", - Disable: true, - Version: 99999, - }, + OnlineDSN: newDSN(nil), + TestDSN: newDSN(nil), AllowOnlineAsTest: false, DropTestTemporary: true, CleanupTestDatabase: false, @@ -236,25 +226,104 @@ var Config = &Configuration{ // Dsn Data source name type Dsn struct { - Net string `yaml:"net"` - Addr string `yaml:"addr"` - Schema string `yaml:"schema"` - - // 数据库用户名和密码可以通过系统环境变量的形式赋值 - User string `yaml:"user"` - Password string `yaml:"password"` - Charset string `yaml:"charset"` - Disable bool `yaml:"disable"` + User string `yaml:"user"` // Usernames + Password string `yaml:"password"` // Password (requires User) + Net string `yaml:"net"` // Network type + Addr string `yaml:"addr"` // Network address (requires Net) + Schema string `yaml:"schema"` // Database name + Charset string `yaml:"charset"` // SET NAMES charset + Collation string `yaml:"collation"` // Connection collation + Loc string `yaml:"loc"` // Location for time.Time values + TLS string `yaml:"tls"` // TLS configuration name + ServerPubKey string `yaml:"server-public-key"` // Server public key name + MaxAllowedPacket int `ymal:"max-allowed-packet"` // Max packet size allowed + Params map[string]string `yaml:"params"` // Other Connection parameters, `SET param=val`, `SET NAMES charset` + Timeout int `yaml:"timeout"` // Dial timeout + ReadTimeout int `yaml:"read-timeout"` // I/O read timeout + WriteTimeout int `yaml:"write-timeout"` // I/O write timeout + + AllowNativePasswords bool `yaml:"allow-native-passwords"` // Allows the native password authentication method + AllowOldPasswords bool `yaml:"allow-old-passwords"` // Allows the old insecure password method + + Disable bool `yaml:"disable"` + Version int `yaml:"-"` // 版本自动检查,不可配置 +} - Timeout int `yaml:"timeout"` - ReadTimeout int `yaml:"read-timeout"` - WriteTimeout int `yaml:"write-timeout"` +// newDSN create default Dsn struct +func newDSN(cfg *mysql.Config) *Dsn { + dsn := &Dsn{ + Net: "tcp", + Schema: "information_schema", + Charset: "utf8", + AllowNativePasswords: true, + Params: make(map[string]string), + MaxAllowedPacket: 4 << 20, // 4 MiB + + // Disable: true, + Version: 99999, + } + if cfg == nil { + return dsn + } + dsn.User = cfg.User + dsn.Password = cfg.Passwd + dsn.Net = cfg.Net + dsn.Addr = cfg.Addr + dsn.Schema = cfg.DBName + dsn.Params = make(map[string]string) + for k, v := range cfg.Params { + dsn.Params[k] = v + } + if _, ok := cfg.Params["charset"]; ok { + dsn.Charset = cfg.Params["charset"] + } + dsn.Collation = cfg.Collation + dsn.Loc = cfg.Loc.String() + dsn.MaxAllowedPacket = cfg.MaxAllowedPacket + dsn.ServerPubKey = cfg.ServerPubKey + dsn.TLS = cfg.TLSConfig + dsn.Timeout = int(cfg.Timeout / time.Second) + dsn.ReadTimeout = int(cfg.ReadTimeout / time.Second) + dsn.WriteTimeout = int(cfg.WriteTimeout / time.Second) + dsn.AllowNativePasswords = cfg.AllowNativePasswords + dsn.AllowOldPasswords = cfg.AllowOldPasswords + return dsn +} - Version int `yaml:"-"` // 版本自动检查,不可配置 +// newMySQLConfig convert Dsn to go-sql-drive Config +func (env *Dsn) newMySQLConifg() (*mysql.Config, error) { + var err error + dsn := mysql.NewConfig() + + dsn.User = env.User + dsn.Passwd = env.Password + dsn.Net = env.Net + dsn.Addr = env.Addr + dsn.DBName = env.Schema + dsn.Params = make(map[string]string) + for k, v := range env.Params { + dsn.Params[k] = v + } + dsn.Params["charset"] = env.Charset + dsn.Collation = env.Collation + dsn.Loc, err = time.LoadLocation(env.Loc) + if err != nil { + return nil, err + } + dsn.MaxAllowedPacket = env.MaxAllowedPacket + dsn.ServerPubKey = env.ServerPubKey + dsn.TLSConfig = env.TLS + dsn.Timeout = time.Duration(env.Timeout) * time.Second + dsn.ReadTimeout = time.Duration(env.ReadTimeout) * time.Second + dsn.WriteTimeout = time.Duration(env.WriteTimeout) * time.Second + dsn.AllowNativePasswords = env.AllowNativePasswords + dsn.AllowOldPasswords = env.AllowOldPasswords + return dsn, err } // 解析命令行DSN输入 func parseDSN(odbc string, d *Dsn) *Dsn { + dsn := newDSN(nil) var addr, user, password, schema, charset string if odbc == FormatDSN(d) { return d @@ -340,30 +409,38 @@ func parseDSN(odbc string, d *Dsn) *Dsn { schema = "information_schema" } - // 默认utf8mb4使用字符集 + // 默认 utf8 使用字符集 if charset == "" { - charset = "utf8mb4" + charset = "utf8" } - dsn := &Dsn{ - Addr: addr, - User: user, - Password: password, - Schema: schema, - Charset: charset, - Disable: false, - Version: 999, - } + dsn.Addr = addr + dsn.User = user + dsn.Password = password + dsn.Schema = schema + dsn.Charset = charset return dsn } +// ParseDSN compatible with old version soar < 0.11.0 +func ParseDSN(odbc string, d *Dsn) *Dsn { + cfg, err := mysql.ParseDSN(odbc) + if err != nil { + return parseDSN(odbc, d) + } + return newDSN(cfg) +} + // FormatDSN 格式化打印DSN func FormatDSN(env *Dsn) string { if env == nil || env.Disable { return "" } - // username:password@ip:port/schema?charset=xxx - return fmt.Sprintf("%s:%s@%s/%s?charset=%s", env.User, env.Password, env.Addr, env.Schema, env.Charset) + dsn, err := env.newMySQLConifg() + if err != nil { + return "" + } + return dsn.FormatDSN() } // SoarVersion soar version information @@ -485,8 +562,8 @@ func readCmdFlags() error { _ = flag.String("config", "", "Config file path") // +++++++++++++++测试环境+++++++++++++++++ - onlineDSN := flag.String("online-dsn", FormatDSN(Config.OnlineDSN), "OnlineDSN, 线上环境数据库配置, username:password@ip:port/schema") - testDSN := flag.String("test-dsn", FormatDSN(Config.TestDSN), "TestDSN, 测试环境数据库配置, username:password@ip:port/schema") + onlineDSN := flag.String("online-dsn", FormatDSN(Config.OnlineDSN), "OnlineDSN, 线上环境数据库配置, username:password@tcp(ip:port)/schema") + testDSN := flag.String("test-dsn", FormatDSN(Config.TestDSN), "TestDSN, 测试环境数据库配置, username:password@tcp(ip:port)/schema") allowOnlineAsTest := flag.Bool("allow-online-as-test", Config.AllowOnlineAsTest, "AllowOnlineAsTest, 允许线上环境也可以当作测试环境") dropTestTemporary := flag.Bool("drop-test-temporary", Config.DropTestTemporary, "DropTestTemporary, 是否清理测试环境产生的临时库表") cleanupTestDatabase := flag.Bool("cleanup-test-database", Config.CleanupTestDatabase, "单次运行清理历史1小时前残余的测试库。") @@ -569,8 +646,8 @@ func readCmdFlags() error { } flag.Parse() - Config.OnlineDSN = parseDSN(*onlineDSN, Config.OnlineDSN) - Config.TestDSN = parseDSN(*testDSN, Config.TestDSN) + Config.OnlineDSN = ParseDSN(*onlineDSN, Config.OnlineDSN) + Config.TestDSN = ParseDSN(*testDSN, Config.TestDSN) Config.AllowOnlineAsTest = *allowOnlineAsTest Config.DropTestTemporary = *dropTestTemporary Config.CleanupTestDatabase = *cleanupTestDatabase diff --git a/common/config_test.go b/common/config_test.go index ba141dfd873f513ad92d77dfb305702ddb5d0bc3..1dead0b6774fb3704cde49ecab749d2ddd0cfc24 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -63,6 +63,7 @@ func TestReadConfigFile(t *testing.T) { func TestParseDSN(t *testing.T) { Log.Debug("Entering function: %s", GetFunctionName()) var dsns = []string{ + // version < 0.11.0 "", "user:password@hostname:3307/database", "user:password@hostname:3307/database?charset=utf8", @@ -81,11 +82,24 @@ func TestParseDSN(t *testing.T) { "@:3307/database", ":3307/database", "/database", + // go-sql-driver dsn + "user@unix(/path/to/socket)/dbname", + "root:pw@unix(/tmp/mysql.sock)/myDatabase?loc=Local", + "user:password@tcp(localhost:5555)/dbname?tls=skip-verify&autocommit=true", + "user:password@/dbname?sql_mode=TRADITIONAL", + "user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname?timeout=90s&collation=utf8mb4_unicode_ci", + "id:password@tcp(your-amazonaws-uri.com:3306)/dbname", + "user@cloudsql(project-id:instance-name)/dbname", + "user@cloudsql(project-id:regionname:instance-name)/dbname", + "user:password@tcp/dbname?charset=utf8mb4,utf8&sys_var=esc%40ped", + "user:password@/dbname", + "user:password@/", } err := GoldenDiff(func() { for _, dsn := range dsns { - pretty.Println(parseDSN(dsn, nil)) + pretty.Println(dsn) + pretty.Println(ParseDSN(dsn, nil)) } }, t.Name(), update) if nil != err { diff --git a/common/example_test.go b/common/example_test.go index ca4fd49353639e09901cb6e4452fe19b9fb77d71..0aa3e00661b7f15124070524fff4d326e08ff44a 100644 --- a/common/example_test.go +++ b/common/example_test.go @@ -20,19 +20,18 @@ import "fmt" func ExampleFormatDSN() { Log.Debug("Entering function: %s", GetFunctionName()) - dsxExp := &Dsn{ - Addr: "127.0.0.1:3306", - Schema: "mysql", - User: "root", - Password: "1t'sB1g3rt", - Charset: "utf8mb4", - Disable: false, - } + dsxExp := newDSN(nil) + dsxExp.Addr = "127.0.0.1:3306" + dsxExp.Schema = "mysql" + dsxExp.User = "root" + dsxExp.Password = "1t'sB1g3rt" + dsxExp.Charset = "utf8mb4" + dsxExp.Disable = false // 根据 &dsn 生成 dsnStr fmt.Println(FormatDSN(dsxExp)) - // Output: root:1t'sB1g3rt@127.0.0.1:3306/mysql?charset=utf8mb4 + // Output: root:1t'sB1g3rt@tcp(127.0.0.1:3306)/mysql?charset=utf8mb4 Log.Debug("Exiting function: %s", GetFunctionName()) } diff --git a/common/testdata/TestParseDSN.golden b/common/testdata/TestParseDSN.golden index 56c8fe7859420dd4623e5dd902c28a8aa0a4e337..fb2701d14c2018e8c848faf8b6c860a7b52b208e 100644 --- a/common/testdata/TestParseDSN.golden +++ b/common/testdata/TestParseDSN.golden @@ -1,18 +1,638 @@ -(*common.Dsn)(nil) -&common.Dsn{Net:"", Addr:"hostname:3307", Schema:"database", User:"user", Password:"password", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"hostname:3307", Schema:"database", User:"user", Password:"password", Charset:"utf8", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"hostname:3307", Schema:"information_schema", User:"user", Password:"password", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"hostname:3306", Schema:"database", User:"user", Password:"password", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"127.0.0.1:3307", Schema:"database", User:"user", Password:"password", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"hostname:3306", Schema:"database", User:"user", Password:"", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"hostname:3306", Schema:"database", User:"user", Password:"pwd:pwd@pwd/pwd", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"127.0.0.1:3306", Schema:"information_schema", User:"user", Password:"password", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"hostname:3307", Schema:"database", User:"", Password:"", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"hostname:3307", Schema:"database", User:"", Password:"", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"hostname:3306", Schema:"information_schema", User:"", Password:"", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"hostname:3306", Schema:"information_schema", User:"", Password:"", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"127.0.0.1:3306", Schema:"database", User:"", Password:"", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"hostname:3307", Schema:"information_schema", User:"", Password:"", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"127.0.0.1:3307", Schema:"database", User:"", Password:"", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"127.0.0.1:3307", Schema:"database", User:"", Password:"", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} -&common.Dsn{Net:"", Addr:"127.0.0.1:3306", Schema:"database", User:"", Password:"", Charset:"utf8mb4", Disable:false, Timeout:0, ReadTimeout:0, WriteTimeout:0, Version:999} + +&common.Dsn{ + User: "", + Password: "", + Net: "tcp", + Addr: "127.0.0.1:3306", + Schema: "", + Charset: "utf8", + Collation: "utf8_general_ci", + Loc: "UTC", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user:password@hostname:3307/database +&common.Dsn{ + User: "user", + Password: "password", + Net: "tcp", + Addr: "hostname:3307", + Schema: "database", + Charset: "utf8", + Collation: "", + Loc: "", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user:password@hostname:3307/database?charset=utf8 +&common.Dsn{ + User: "user", + Password: "password", + Net: "tcp", + Addr: "hostname:3307", + Schema: "database", + Charset: "utf8", + Collation: "", + Loc: "", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user:password@hostname:3307 +&common.Dsn{ + User: "user", + Password: "password", + Net: "tcp", + Addr: "hostname:3307", + Schema: "information_schema", + Charset: "utf8", + Collation: "", + Loc: "", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user:password@hostname:/database +&common.Dsn{ + User: "user", + Password: "password", + Net: "tcp", + Addr: "hostname:3306", + Schema: "database", + Charset: "utf8", + Collation: "", + Loc: "", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user:password@:3307/database +&common.Dsn{ + User: "user", + Password: "password", + Net: "tcp", + Addr: "127.0.0.1:3307", + Schema: "database", + Charset: "utf8", + Collation: "", + Loc: "", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user@hostname/database +&common.Dsn{ + User: "user", + Password: "", + Net: "tcp", + Addr: "hostname:3306", + Schema: "database", + Charset: "utf8", + Collation: "", + Loc: "", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user:pwd:pwd@pwd/pwd@hostname/database +&common.Dsn{ + User: "user", + Password: "pwd:pwd@pwd/pwd", + Net: "tcp", + Addr: "hostname:3306", + Schema: "database", + Charset: "utf8", + Collation: "", + Loc: "", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user:password@ +&common.Dsn{ + User: "user", + Password: "password", + Net: "tcp", + Addr: "127.0.0.1:3306", + Schema: "information_schema", + Charset: "utf8", + Collation: "", + Loc: "", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +hostname:3307/database +&common.Dsn{ + User: "", + Password: "", + Net: "tcp", + Addr: "hostname:3307", + Schema: "database", + Charset: "utf8", + Collation: "", + Loc: "", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +@hostname:3307/database +&common.Dsn{ + User: "", + Password: "", + Net: "tcp", + Addr: "hostname:3307", + Schema: "database", + Charset: "utf8", + Collation: "", + Loc: "", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +@hostname +&common.Dsn{ + User: "", + Password: "", + Net: "tcp", + Addr: "hostname:3306", + Schema: "information_schema", + Charset: "utf8", + Collation: "", + Loc: "", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +hostname +&common.Dsn{ + User: "", + Password: "", + Net: "tcp", + Addr: "hostname:3306", + Schema: "information_schema", + Charset: "utf8", + Collation: "", + Loc: "", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +@/database +&common.Dsn{ + User: "", + Password: "", + Net: "tcp", + Addr: "127.0.0.1:3306", + Schema: "database", + Charset: "utf8", + Collation: "utf8_general_ci", + Loc: "UTC", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +@hostname:3307 +&common.Dsn{ + User: "", + Password: "", + Net: "tcp", + Addr: "hostname:3307", + Schema: "information_schema", + Charset: "utf8", + Collation: "", + Loc: "", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +@:3307/database +&common.Dsn{ + User: "", + Password: "", + Net: "tcp", + Addr: "127.0.0.1:3307", + Schema: "database", + Charset: "utf8", + Collation: "", + Loc: "", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +:3307/database +&common.Dsn{ + User: "", + Password: "", + Net: "tcp", + Addr: "127.0.0.1:3307", + Schema: "database", + Charset: "utf8", + Collation: "", + Loc: "", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +/database +&common.Dsn{ + User: "", + Password: "", + Net: "tcp", + Addr: "127.0.0.1:3306", + Schema: "database", + Charset: "utf8", + Collation: "utf8_general_ci", + Loc: "UTC", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user@unix(/path/to/socket)/dbname +&common.Dsn{ + User: "user", + Password: "", + Net: "unix", + Addr: "/path/to/socket", + Schema: "dbname", + Charset: "utf8", + Collation: "utf8_general_ci", + Loc: "UTC", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +root:pw@unix(/tmp/mysql.sock)/myDatabase?loc=Local +&common.Dsn{ + User: "root", + Password: "pw", + Net: "unix", + Addr: "/tmp/mysql.sock", + Schema: "myDatabase", + Charset: "utf8", + Collation: "utf8_general_ci", + Loc: "Local", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user:password@tcp(localhost:5555)/dbname?tls=skip-verify&autocommit=true +&common.Dsn{ + User: "user", + Password: "password", + Net: "tcp", + Addr: "localhost:5555", + Schema: "dbname", + Charset: "utf8", + Collation: "utf8_general_ci", + Loc: "UTC", + TLS: "skip-verify", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {"autocommit":"true"}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user:password@/dbname?sql_mode=TRADITIONAL +&common.Dsn{ + User: "user", + Password: "password", + Net: "tcp", + Addr: "127.0.0.1:3306", + Schema: "dbname", + Charset: "utf8", + Collation: "utf8_general_ci", + Loc: "UTC", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {"sql_mode":"TRADITIONAL"}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname?timeout=90s&collation=utf8mb4_unicode_ci +&common.Dsn{ + User: "user", + Password: "password", + Net: "tcp", + Addr: "[de:ad:be:ef::ca:fe]:80", + Schema: "dbname", + Charset: "utf8", + Collation: "utf8mb4_unicode_ci", + Loc: "UTC", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 90, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +id:password@tcp(your-amazonaws-uri.com:3306)/dbname +&common.Dsn{ + User: "id", + Password: "password", + Net: "tcp", + Addr: "your-amazonaws-uri.com:3306", + Schema: "dbname", + Charset: "utf8", + Collation: "utf8_general_ci", + Loc: "UTC", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user@cloudsql(project-id:instance-name)/dbname +&common.Dsn{ + User: "user", + Password: "", + Net: "cloudsql", + Addr: "project-id:instance-name", + Schema: "dbname", + Charset: "utf8", + Collation: "utf8_general_ci", + Loc: "UTC", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user@cloudsql(project-id:regionname:instance-name)/dbname +&common.Dsn{ + User: "user", + Password: "", + Net: "cloudsql", + Addr: "project-id:regionname:instance-name", + Schema: "dbname", + Charset: "utf8", + Collation: "utf8_general_ci", + Loc: "UTC", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user:password@tcp/dbname?charset=utf8mb4,utf8&sys_var=esc%40ped +&common.Dsn{ + User: "user", + Password: "password", + Net: "tcp", + Addr: "127.0.0.1:3306", + Schema: "dbname", + Charset: "utf8mb4,utf8", + Collation: "utf8_general_ci", + Loc: "UTC", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {"charset":"utf8mb4,utf8", "sys_var":"esc@ped"}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user:password@/dbname +&common.Dsn{ + User: "user", + Password: "password", + Net: "tcp", + Addr: "127.0.0.1:3306", + Schema: "dbname", + Charset: "utf8", + Collation: "utf8_general_ci", + Loc: "UTC", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} +user:password@/ +&common.Dsn{ + User: "user", + Password: "password", + Net: "tcp", + Addr: "127.0.0.1:3306", + Schema: "", + Charset: "utf8", + Collation: "utf8_general_ci", + Loc: "UTC", + TLS: "", + ServerPubKey: "", + MaxAllowedPacket: 4194304, + Params: {}, + Timeout: 0, + ReadTimeout: 0, + WriteTimeout: 0, + AllowNativePasswords: true, + AllowOldPasswords: false, + Disable: true, + Version: 99999, +} diff --git a/database/mysql.go b/database/mysql.go index 738f1a9878ab13b8fb7c11da40752823e5c38c22..a623c557439f53058a606ba2c967632135b8981b 100644 --- a/database/mysql.go +++ b/database/mysql.go @@ -53,14 +53,7 @@ type QueryResult struct { // NewConnector 创建新连接 func NewConnector(dsn *common.Dsn) (*Connector, error) { - conn, err := sql.Open("mysql", fmt.Sprintf("%s:%s@%s(%s)/%s?parseTime=true&charset=%s", - dsn.User, - dsn.Password, - dsn.Net, - dsn.Addr, - dsn.Schema, - dsn.Charset, - )) + conn, err := sql.Open("mysql", common.FormatDSN(dsn)) if err != nil { return nil, err } diff --git a/env/env.go b/env/env.go index 9a0cf1a89ff5137d333f62d75e432c8f5b86b03d..a8c1e55e40d0645e139591b923da6524ca02ccf3 100644 --- a/env/env.go +++ b/env/env.go @@ -73,7 +73,7 @@ func BuildEnv() (*VirtualEnv, *database.Connector) { // 连接线上环境 // 如果未配置线上环境线测试环境配置为线上环境 - if common.Config.OnlineDSN.Addr == "" { + if common.Config.OnlineDSN.User == "" { common.Log.Warn("BuildEnv AllowOnlineAsTest: OnlineDSN not config, use TestDSN: %s:********@%s/%s as OnlineDSN", vEnv.User, vEnv.Addr, vEnv.Database) common.Config.OnlineDSN = common.Config.TestDSN @@ -235,7 +235,7 @@ func (vEnv *VirtualEnv) BuildVirtualEnv(rEnv *database.Connector, SQLs ...string case *sqlparser.Use: // 如果是use语句,则更改基础环配置 if _, ok := meta[stmt.DBName.String()]; !ok { - // 如果USE了一个线上环境不存在的数据库,将创建该数据库,字符集默认utf8mb4 + // 如果USE了一个线上环境不存在的数据库,将创建该数据库 meta[stmt.DBName.String()] = common.NewDB(stmt.DBName.String()) rEnv.Database = stmt.DBName.String() @@ -367,7 +367,7 @@ func (vEnv *VirtualEnv) createDatabase(rEnv *database.Connector) error { ddl, err := rEnv.ShowCreateDatabase(rEnv.Database) if err != nil { common.Log.Warning("createDatabase, rEnv.ShowCreateDatabase Error : %v", err) - ddl = fmt.Sprintf("create database `%s` character set utf8mb4", rEnv.Database) + ddl = fmt.Sprintf("create database `%s` character set %s", rEnv.Database, rEnv.Charset) } ddl = strings.Replace(ddl, rEnv.Database, dbHash, -1) diff --git a/genver.sh b/genver.sh index 52550257e4de141d6e15d5aa4bd0714fc3f52495..56cc0ff8e11a126445ba36f54b618a03ba4df976 100755 --- a/genver.sh +++ b/genver.sh @@ -1,9 +1,11 @@ #!/bin/bash ## Generate Repository Version -version="$(git log --date=iso --pretty=format:"%cd" -1) $(git describe --tags --always)" +tag="$(git describe --tags --always)" +version="$(git log --date=iso --pretty=format:"%cd" -1) ${tag}" if [ "X${version}" == "X" ]; then version="not a git repo" + tag="not a git repo" fi git_dirty=$(git diff --no-ext-diff 2>/dev/null | wc -l) @@ -29,3 +31,5 @@ const ( DevPath = "${dev_path}" ) EOF + +echo "${tag}" | awk -F '-' '{print $1}' > VERSION