diff --git a/common/config.go b/common/config.go index 32e83cdfe0032e5dd3109bcf8fae0f912451d6b9..8f2b451d528eeb7235148667df805669760de7b5 100644 --- a/common/config.go +++ b/common/config.go @@ -256,7 +256,8 @@ func parseDSN(odbc string, d *dsn) *dsn { } if d != nil { - addr = d.Addr + // 原来有个判断,后来判断条件被删除了就导致第一次addr无论如何都会被修改。所以这边先注释掉 + //addr = d.Addr user = d.User password = d.Password schema = d.Schema @@ -269,60 +270,55 @@ func parseDSN(odbc string, d *dsn) *dsn { return &dsn{Disable: true} } - // username:password@ip:port/database - l1 := strings.Split(odbc, "@") - if len(l1) < 2 { - if strings.HasPrefix(l1[0], ":") { - // ":port/database" - l2 := strings.Split(strings.TrimLeft(l1[0], ":"), "/") - if l2[0] == "" { - addr = strings.Split(addr, ":")[0] + ":3306" - if len(l2) > 1 { - schema = strings.Split(l2[1], "?")[0] - } - } else { - addr = strings.Split(addr, ":")[0] + ":" + l2[0] - if len(l2) > 1 { - schema = strings.Split(l2[1], "?")[0] - } - } - } else if strings.HasPrefix(l1[0], "/") { - // "/database" - l2 := strings.TrimLeft(l1[0], "/") - schema = l2 - } else { - // ip:port/database - l2 := strings.Split(l1[0], "/") - if len(l2) == 2 { - addr = l2[0] - schema = strings.Split(l2[1], "?")[0] - } else { - addr = l2[0] - } - } + var userInfo, hostInfo, query string + + // DSN 格式匹配 + // userInfo@hostInfo/database + if res := regexp.MustCompile( `^(.*)@(.*?)/(.*?)($|\?)(.*)`).FindStringSubmatch(odbc); len(res) > 5 { + userInfo = res[1] + hostInfo = res[2] + schema = res[3] + query = res[5] + + // hostInfo/database + } else if res := regexp.MustCompile(`^(.*)/(.*?)($|\?)(.*)`).FindStringSubmatch(odbc); len(res) > 4 { + hostInfo = res[1] + schema = res[2] + query = res[4] + + // userInfo@hostInfo + } else if res := regexp.MustCompile(`^(.*)@(.*?)($|\?)(.*)`).FindStringSubmatch(odbc); len(res) > 4 { + userInfo = res[1] + hostInfo = res[2] + query = res[4] + + // hostInfo } else { - // user:password - l2 := strings.Split(l1[0], ":") - if len(l2) == 2 { - user = l2[0] - password = l2[1] - } else { - user = l2[0] - } - // ip:port/database - l3 := strings.Split(l1[1], "/") - if len(l3) == 2 { - addr = l3[0] - schema = strings.Split(l3[1], "?")[0] - } else { - addr = l3[0] - } + hostInfo = odbc + } + + // 解析用户信息 + if userInfo != "" { + user = strings.Split(userInfo, ":")[0] + // 防止密码中含有与用户名相同的字符, 所以用正则替换, 剩下的就是密码 + password = strings.TrimLeft(regexp.MustCompile("^" + user).ReplaceAllString(userInfo, ""), ":") } - // 其他flag参数,目前只支持charset :( - if len(strings.Split(odbc, "?")) > 1 { - flags := strings.Split(strings.Split(odbc, "?")[1], "&") - for _, f := range flags { + // 解析主机信息 + host := strings.Split(hostInfo, ":")[0] + port := strings.TrimLeft(strings.Replace(hostInfo, host, "", 1), ":") + if host == "" { + host = "127.0.0.1" + } + if port == ""{ + port = "3306" + } + addr = host + ":" + port + + // 解析查询字符串 + if (query != "") { + params := strings.Split(query, "&") + for _, f := range params { attr := strings.Split(f, "=") if len(attr) > 1 { arg := strings.TrimSpace(attr[0]) @@ -336,20 +332,6 @@ func parseDSN(odbc string, d *dsn) *dsn { } } - // 自动补端口 - if !strings.Contains(addr, ":") { - addr = addr + ":3306" - } else { - if strings.HasSuffix(addr, ":") { - addr = addr + "3306" - } - } - - // 默认走127.0.0.1 - if strings.HasPrefix(addr, ":") { - addr = "127.0.0.1" + addr - } - // 默认用information_schema库 if schema == "" { schema = "information_schema" diff --git a/common/config_test.go b/common/config_test.go index 6b61aef2f93a8aa17125ddae4e0cb77c8f5f7a44..3e0b5b3d01d773ba0111230f49cff7964acd0a16 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -48,6 +48,8 @@ func TestParseDSN(t *testing.T) { "user:password@hostname:3307", "user:password@hostname:/database", "user:password@:3307/database", + "user@hostname/dbname", + "user:pwd:pwd@pwd/pwd@hostname/dbname", "user:password@", "hostname:3307/database", "@hostname:3307/database", diff --git a/common/testdata/TestParseDSN.golden b/common/testdata/TestParseDSN.golden index 749a4999a696d291298b6a54dfba65d63ac2ae43..0cf0dcf02d2661e48483dae7857b974230eb1651 100644 --- a/common/testdata/TestParseDSN.golden +++ b/common/testdata/TestParseDSN.golden @@ -3,6 +3,8 @@ &common.dsn{Addr:"hostname:3307", Schema:"information_schema", User:"user", Password:"password", Charset:"utf8mb4", Disable:false, Version:999} &common.dsn{Addr:"hostname:3306", Schema:"database", User:"user", Password:"password", Charset:"utf8mb4", Disable:false, Version:999} &common.dsn{Addr:"127.0.0.1:3307", Schema:"database", User:"user", Password:"password", Charset:"utf8mb4", Disable:false, Version:999} +&common.dsn{Addr:"hostname:3306", Schema:"dbname", User:"user", Password:"", Charset:"utf8mb4", Disable:false, Version:999} +&common.dsn{Addr:"hostname:3306", Schema:"dbname", User:"user", Password:"pwd:pwd@pwd/pwd", Charset:"utf8mb4", Disable:false, Version:999} &common.dsn{Addr:"127.0.0.1:3306", Schema:"information_schema", User:"user", Password:"password", Charset:"utf8mb4", Disable:false, Version:999} &common.dsn{Addr:"hostname:3307", Schema:"database", User:"", Password:"", Charset:"utf8mb4", Disable:false, Version:999} &common.dsn{Addr:"hostname:3307", Schema:"database", User:"", Password:"", Charset:"utf8mb4", Disable:false, Version:999}