// 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 ( "database/sql" "fmt" "net/url" "strings" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/text/gregex" ) // Open creates and returns an underlying sql.DB object for mysql. // 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 = 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&...¶mN=valueN] if config.Link != "" { // ============================================================================ // Deprecated from v2.2.0. // ============================================================================ source = config.Link // Custom changing the schema in runtime. if config.Name != "" { source, _ = gregex.ReplaceString(`/([\w\.\-]+)+`, "/"+config.Name, source) } } else { 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, portStr, config.Name, config.Charset, ) if config.Timezone != "" { if strings.Contains(config.Timezone, "/") { config.Timezone = url.QueryEscape(config.Timezone) } source = fmt.Sprintf("%s&loc=%s", source, config.Timezone) } if config.Extra != "" { source = fmt.Sprintf("%s&%s", source, config.Extra) } } return source }