未验证 提交 45a48465 编写于 作者: martianzhang's avatar martianzhang 提交者: GitHub

Merge pull request #167 from xiyangxixian/master

 DSN 解析优化, 并支持密码特殊字符
...@@ -256,7 +256,8 @@ func parseDSN(odbc string, d *dsn) *dsn { ...@@ -256,7 +256,8 @@ func parseDSN(odbc string, d *dsn) *dsn {
} }
if d != nil { if d != nil {
addr = d.Addr // 原来有个判断,后来判断条件被删除了就导致第一次addr无论如何都会被修改。所以这边先注释掉
//addr = d.Addr
user = d.User user = d.User
password = d.Password password = d.Password
schema = d.Schema schema = d.Schema
...@@ -269,60 +270,55 @@ func parseDSN(odbc string, d *dsn) *dsn { ...@@ -269,60 +270,55 @@ func parseDSN(odbc string, d *dsn) *dsn {
return &dsn{Disable: true} return &dsn{Disable: true}
} }
// username:password@ip:port/database var userInfo, hostInfo, query string
l1 := strings.Split(odbc, "@")
if len(l1) < 2 { // DSN 格式匹配
if strings.HasPrefix(l1[0], ":") { // userInfo@hostInfo/database
// ":port/database" if res := regexp.MustCompile( `^(.*)@(.*?)/(.*?)($|\?)(.*)`).FindStringSubmatch(odbc); len(res) > 5 {
l2 := strings.Split(strings.TrimLeft(l1[0], ":"), "/") userInfo = res[1]
if l2[0] == "" { hostInfo = res[2]
addr = strings.Split(addr, ":")[0] + ":3306" schema = res[3]
if len(l2) > 1 { query = res[5]
schema = strings.Split(l2[1], "?")[0]
} // hostInfo/database
} else { } else if res := regexp.MustCompile(`^(.*)/(.*?)($|\?)(.*)`).FindStringSubmatch(odbc); len(res) > 4 {
addr = strings.Split(addr, ":")[0] + ":" + l2[0] hostInfo = res[1]
if len(l2) > 1 { schema = res[2]
schema = strings.Split(l2[1], "?")[0] query = res[4]
}
} // userInfo@hostInfo
} else if strings.HasPrefix(l1[0], "/") { } else if res := regexp.MustCompile(`^(.*)@(.*?)($|\?)(.*)`).FindStringSubmatch(odbc); len(res) > 4 {
// "/database" userInfo = res[1]
l2 := strings.TrimLeft(l1[0], "/") hostInfo = res[2]
schema = l2 query = res[4]
} else {
// ip:port/database // hostInfo
l2 := strings.Split(l1[0], "/")
if len(l2) == 2 {
addr = l2[0]
schema = strings.Split(l2[1], "?")[0]
} else {
addr = l2[0]
}
}
} else { } else {
// user:password hostInfo = odbc
l2 := strings.Split(l1[0], ":") }
if len(l2) == 2 {
user = l2[0] // 解析用户信息
password = l2[1] if userInfo != "" {
} else { user = strings.Split(userInfo, ":")[0]
user = l2[0] // 防止密码中含有与用户名相同的字符, 所以用正则替换, 剩下的就是密码
} password = strings.TrimLeft(regexp.MustCompile("^" + user).ReplaceAllString(userInfo, ""), ":")
// 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]
}
} }
// 其他flag参数,目前只支持charset :( // 解析主机信息
if len(strings.Split(odbc, "?")) > 1 { host := strings.Split(hostInfo, ":")[0]
flags := strings.Split(strings.Split(odbc, "?")[1], "&") port := strings.TrimLeft(strings.Replace(hostInfo, host, "", 1), ":")
for _, f := range flags { 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, "=") attr := strings.Split(f, "=")
if len(attr) > 1 { if len(attr) > 1 {
arg := strings.TrimSpace(attr[0]) arg := strings.TrimSpace(attr[0])
...@@ -336,20 +332,6 @@ func parseDSN(odbc string, d *dsn) *dsn { ...@@ -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库 // 默认用information_schema库
if schema == "" { if schema == "" {
schema = "information_schema" schema = "information_schema"
......
...@@ -48,6 +48,8 @@ func TestParseDSN(t *testing.T) { ...@@ -48,6 +48,8 @@ func TestParseDSN(t *testing.T) {
"user:password@hostname:3307", "user:password@hostname:3307",
"user:password@hostname:/database", "user:password@hostname:/database",
"user:password@:3307/database", "user:password@:3307/database",
"user@hostname/dbname",
"user:pwd:pwd@pwd/pwd@hostname/dbname",
"user:password@", "user:password@",
"hostname:3307/database", "hostname:3307/database",
"@hostname:3307/database", "@hostname:3307/database",
......
...@@ -3,6 +3,8 @@ ...@@ -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: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:"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:"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:"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}
&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}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册