Skip to content

Commit

Permalink
fix(database/gdb): unix socket connection support for mysql (#3872)
Browse files Browse the repository at this point in the history
  • Loading branch information
gqcn authored Oct 21, 2024
1 parent 7dd38a1 commit e179e1d
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 14 deletions.
33 changes: 20 additions & 13 deletions contrib/drivers/mysql/mysql_open.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ package mysql
import (
"database/sql"
"fmt"

"net/url"
"strings"

Expand All @@ -23,9 +22,21 @@ import (
// Note that it converts time.Time argument to local timezone in default.
func (d *Driver) Open(config *gdb.ConfigNode) (db *sql.DB, err error) {
var (
source string
source = configNodeToSource(config)
underlyingDriverName = "mysql"
)
if db, err = sql.Open(underlyingDriverName, source); err != nil {
err = gerror.WrapCodef(
gcode.CodeDbOperationError, err,
`sql.Open failed for driver "%s" by source "%s"`, underlyingDriverName, source,
)
return nil, err
}
return
}

func configNodeToSource(config *gdb.ConfigNode) string {
var source string
// [username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]
if config.Link != "" {
// ============================================================================
Expand All @@ -37,10 +48,13 @@ func (d *Driver) Open(config *gdb.ConfigNode) (db *sql.DB, err error) {
source, _ = gregex.ReplaceString(`/([\w\.\-]+)+`, "/"+config.Name, source)
}
} else {
// TODO: Do not set charset when charset is not specified (in v2.5.0)
var portStr string
if config.Port != "" {
portStr = ":" + config.Port
}
source = fmt.Sprintf(
"%s:%s@%s(%s:%s)/%s?charset=%s",
config.User, config.Pass, config.Protocol, config.Host, config.Port, config.Name, config.Charset,
"%s:%s@%s(%s%s)/%s?charset=%s",
config.User, config.Pass, config.Protocol, config.Host, portStr, config.Name, config.Charset,
)
if config.Timezone != "" {
if strings.Contains(config.Timezone, "/") {
Expand All @@ -52,12 +66,5 @@ func (d *Driver) Open(config *gdb.ConfigNode) (db *sql.DB, err error) {
source = fmt.Sprintf("%s&%s", source, config.Extra)
}
}
if db, err = sql.Open(underlyingDriverName, source); err != nil {
err = gerror.WrapCodef(
gcode.CodeDbOperationError, err,
`sql.Open failed for driver "%s" by source "%s"`, underlyingDriverName, source,
)
return nil, err
}
return
return source
}
30 changes: 30 additions & 0 deletions contrib/drivers/mysql/mysql_z_unit_internal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.

package mysql

import (
"testing"

"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/test/gtest"
)

func Test_configNodeToSource(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
configNode := &gdb.ConfigNode{
Host: "/tmp/mysql.sock",
Port: "",
User: "username",
Pass: "password",
Name: "dbname",
Type: "mysql",
Protocol: "unix",
}
source := configNodeToSource(configNode)
t.Assert(source, "username:password@unix(/tmp/mysql.sock)/dbname?charset=")
})
}
18 changes: 17 additions & 1 deletion database/gdb/gdb_z_mysql_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ func Test_parseConfigNodeLink_WithType(t *testing.T) {
t.Assert(newNode.Charset, defaultCharset)
t.Assert(newNode.Protocol, `tcp`)
})
// #3755
// https://github.com/gogf/gf/issues/3755
gtest.C(t, func(t *gtest.T) {
node := &ConfigNode{
Link: "mysql:user:pwd@tcp(rdsid.mysql.rds.aliyuncs.com)/dbname?charset=utf8&loc=Local",
Expand All @@ -248,6 +248,22 @@ func Test_parseConfigNodeLink_WithType(t *testing.T) {
t.Assert(newNode.Charset, `utf8`)
t.Assert(newNode.Protocol, `tcp`)
})
// https://github.com/gogf/gf/issues/3862
gtest.C(t, func(t *gtest.T) {
node := &ConfigNode{
Link: "mysql:username:password@unix(/tmp/mysql.sock)/dbname",
}
newNode := parseConfigNodeLink(node)
t.Assert(newNode.Type, `mysql`)
t.Assert(newNode.User, `username`)
t.Assert(newNode.Pass, `password`)
t.Assert(newNode.Host, `/tmp/mysql.sock`)
t.Assert(newNode.Port, ``)
t.Assert(newNode.Name, `dbname`)
t.Assert(newNode.Extra, ``)
t.Assert(newNode.Charset, `utf8`)
t.Assert(newNode.Protocol, `unix`)
})
}

func Test_Func_doQuoteWord(t *testing.T) {
Expand Down

0 comments on commit e179e1d

Please sign in to comment.