From ca1671a04ab68fe914ebf0f77c28feba14886b5d Mon Sep 17 00:00:00 2001 From: Ichinose Shogo <shogo82148@gmail.com> Date: Sat, 7 Apr 2018 15:38:14 +0900 Subject: [PATCH 01/14] Implement Connector and DriverContext interface --- connector.go | 126 +++++++++++++++++++++++++++++++++++++++++++ driver_go110.go | 27 ++++++++++ driver_go110_test.go | 15 ++++++ 3 files changed, 168 insertions(+) create mode 100644 connector.go create mode 100644 driver_go110.go create mode 100644 driver_go110_test.go diff --git a/connector.go b/connector.go new file mode 100644 index 000000000..d96edcf32 --- /dev/null +++ b/connector.go @@ -0,0 +1,126 @@ +// Go MySQL Driver - A MySQL-Driver for Go's database/sql package +// +// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at http://mozilla.org/MPL/2.0/. + +// +build go1.10 + +package mysql + +import ( + "context" + "database/sql/driver" + "net" +) + +// Connector is a driver in a fixed configuration. +type Connector struct { + Config *Config +} + +// Connect implements driver.Connector interface. +// Connect returns a connection to the database. +func (c Connector) Connect(ctx context.Context) (driver.Conn, error) { + var err error + + // New mysqlConn + mc := &mysqlConn{ + maxAllowedPacket: maxPacketSize, + maxWriteSize: maxPacketSize - 1, + closech: make(chan struct{}), + cfg: c.Config, + } + mc.parseTime = mc.cfg.ParseTime + + // Connect to Server + // TODO: needs RegisterDialContext + if dial, ok := dials[mc.cfg.Net]; ok { + mc.netConn, err = dial(mc.cfg.Addr) + } else { + nd := net.Dialer{Timeout: mc.cfg.Timeout} + mc.netConn, err = nd.DialContext(ctx, mc.cfg.Net, mc.cfg.Addr) + } + if err != nil { + return nil, err + } + + // Enable TCP Keepalives on TCP connections + if tc, ok := mc.netConn.(*net.TCPConn); ok { + if err := tc.SetKeepAlive(true); err != nil { + // Don't send COM_QUIT before handshake. + mc.netConn.Close() + mc.netConn = nil + return nil, err + } + } + + // Call startWatcher for context support (From Go 1.8) + if s, ok := interface{}(mc).(watcher); ok { + s.startWatcher() + } + if err := mc.watchCancel(ctx); err != nil { + return nil, err + } + defer mc.finish() + + mc.buf = newBuffer(mc.netConn) + + // Set I/O timeouts + mc.buf.timeout = mc.cfg.ReadTimeout + mc.writeTimeout = mc.cfg.WriteTimeout + + // Reading Handshake Initialization Packet + cipher, err := mc.readInitPacket() + if err != nil { + mc.cleanup() + return nil, err + } + + // Send Client Authentication Packet + if err = mc.writeAuthPacket(cipher); err != nil { + mc.cleanup() + return nil, err + } + + // Handle response to auth packet, switch methods if possible + if err = handleAuthResult(mc, cipher); err != nil { + // Authentication failed and MySQL has already closed the connection + // (https://dev.mysql.com/doc/internals/en/authentication-fails.html). + // Do not send COM_QUIT, just cleanup and return the error. + mc.cleanup() + return nil, err + } + + if mc.cfg.MaxAllowedPacket > 0 { + mc.maxAllowedPacket = mc.cfg.MaxAllowedPacket + } else { + // Get max allowed packet size + maxap, err := mc.getSystemVar("max_allowed_packet") + if err != nil { + mc.Close() + return nil, err + } + mc.maxAllowedPacket = stringToInt(maxap) - 1 + } + if mc.maxAllowedPacket < maxPacketSize { + mc.maxWriteSize = mc.maxAllowedPacket + } + + // Handle DSN Params + err = mc.handleParams() + if err != nil { + mc.Close() + return nil, err + } + + return mc, nil +} + +// Driver implements driver.Connector interface. +// Driver returns &MySQLDriver{}. +func (c Connector) Driver() driver.Driver { + return &MySQLDriver{} +} diff --git a/driver_go110.go b/driver_go110.go new file mode 100644 index 000000000..5389e3107 --- /dev/null +++ b/driver_go110.go @@ -0,0 +1,27 @@ +// Go MySQL Driver - A MySQL-Driver for Go's database/sql package +// +// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at http://mozilla.org/MPL/2.0/. + +// +build go1.10 + +package mysql + +import ( + "database/sql/driver" +) + +// OpenConnector implements driver.DriverContext. +func (d MySQLDriver) OpenConnector(dsn string) (driver.Connector, error) { + c, err := ParseDSN(dsn) + if err != nil { + return nil, err + } + + return Connector{ + Config: c, + }, nil +} diff --git a/driver_go110_test.go b/driver_go110_test.go new file mode 100644 index 000000000..daa47bae6 --- /dev/null +++ b/driver_go110_test.go @@ -0,0 +1,15 @@ +// Go MySQL Driver - A MySQL-Driver for Go's database/sql package +// +// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at http://mozilla.org/MPL/2.0/. + +package mysql + +import ( + "database/sql/driver" +) + +var _ driver.DriverContext = &MySQLDriver{} From ccd26221cb6abfc712c15d479695faa8684b7b61 Mon Sep 17 00:00:00 2001 From: Ichinose Shogo <shogo82148@gmail.com> Date: Sat, 7 Apr 2018 15:48:34 +0900 Subject: [PATCH 02/14] no need to check the driver implements the watcher interface. because Connector.Connect is built with Go1.10 or higher. --- connector.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/connector.go b/connector.go index d96edcf32..95af2faf7 100644 --- a/connector.go +++ b/connector.go @@ -58,9 +58,7 @@ func (c Connector) Connect(ctx context.Context) (driver.Conn, error) { } // Call startWatcher for context support (From Go 1.8) - if s, ok := interface{}(mc).(watcher); ok { - s.startWatcher() - } + mc.startWatcher() if err := mc.watchCancel(ctx); err != nil { return nil, err } From cc53a93b7a7352ab0561a5803fc21ca5f5ee4f5b Mon Sep 17 00:00:00 2001 From: Ichinose Shogo <shogo82148@gmail.com> Date: Sat, 7 Apr 2018 15:51:25 +0900 Subject: [PATCH 03/14] add missing build tag. --- driver_go110_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/driver_go110_test.go b/driver_go110_test.go index daa47bae6..8ac834f33 100644 --- a/driver_go110_test.go +++ b/driver_go110_test.go @@ -6,6 +6,8 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at http://mozilla.org/MPL/2.0/. +// +build go1.10 + package mysql import ( From 877ae16b36f6e6dd6fcd710960e951fb76130f05 Mon Sep 17 00:00:00 2001 From: Ichinose Shogo <shogo82148@gmail.com> Date: Sat, 16 Jun 2018 19:07:53 +0900 Subject: [PATCH 04/14] Rename new files. because the Go toolchain has special support for this naming scheme. --- connector.go => connector_go1.10.go | 9 +++++---- driver_go110_test.go => driver_go1.10_test.go | 4 +--- 2 files changed, 6 insertions(+), 7 deletions(-) rename connector.go => connector_go1.10.go (95%) rename driver_go110_test.go => driver_go1.10_test.go (81%) diff --git a/connector.go b/connector_go1.10.go similarity index 95% rename from connector.go rename to connector_go1.10.go index 95af2faf7..4357ec3d9 100644 --- a/connector.go +++ b/connector_go1.10.go @@ -1,13 +1,11 @@ // Go MySQL Driver - A MySQL-Driver for Go's database/sql package // -// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. +// Copyright 2018 The Go-MySQL-Driver Authors. All rights reserved. // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at http://mozilla.org/MPL/2.0/. -// +build go1.10 - package mysql import ( @@ -37,7 +35,10 @@ func (c Connector) Connect(ctx context.Context) (driver.Conn, error) { // Connect to Server // TODO: needs RegisterDialContext - if dial, ok := dials[mc.cfg.Net]; ok { + dialsLock.RLock() + dial, ok := dials[mc.cfg.Net] + dialsLock.RUnlock() + if ok { mc.netConn, err = dial(mc.cfg.Addr) } else { nd := net.Dialer{Timeout: mc.cfg.Timeout} diff --git a/driver_go110_test.go b/driver_go1.10_test.go similarity index 81% rename from driver_go110_test.go rename to driver_go1.10_test.go index 8ac834f33..7641e4b61 100644 --- a/driver_go110_test.go +++ b/driver_go1.10_test.go @@ -1,13 +1,11 @@ // Go MySQL Driver - A MySQL-Driver for Go's database/sql package // -// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved. +// Copyright 2018 The Go-MySQL-Driver Authors. All rights reserved. // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at http://mozilla.org/MPL/2.0/. -// +build go1.10 - package mysql import ( From 0aca26bcac8989a02fe2f484b99325cd2f4a0a70 Mon Sep 17 00:00:00 2001 From: Ichinose Shogo <shogo82148@gmail.com> Date: Sat, 16 Jun 2018 19:12:11 +0900 Subject: [PATCH 05/14] move Connect to Config from Connector. --- connector_go1.10.go | 11 +++-------- driver_go110.go | 4 +--- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/connector_go1.10.go b/connector_go1.10.go index 4357ec3d9..90b1a86d6 100644 --- a/connector_go1.10.go +++ b/connector_go1.10.go @@ -14,14 +14,9 @@ import ( "net" ) -// Connector is a driver in a fixed configuration. -type Connector struct { - Config *Config -} - // Connect implements driver.Connector interface. // Connect returns a connection to the database. -func (c Connector) Connect(ctx context.Context) (driver.Conn, error) { +func (c *Config) Connect(ctx context.Context) (driver.Conn, error) { var err error // New mysqlConn @@ -29,7 +24,7 @@ func (c Connector) Connect(ctx context.Context) (driver.Conn, error) { maxAllowedPacket: maxPacketSize, maxWriteSize: maxPacketSize - 1, closech: make(chan struct{}), - cfg: c.Config, + cfg: c, } mc.parseTime = mc.cfg.ParseTime @@ -120,6 +115,6 @@ func (c Connector) Connect(ctx context.Context) (driver.Conn, error) { // Driver implements driver.Connector interface. // Driver returns &MySQLDriver{}. -func (c Connector) Driver() driver.Driver { +func (c *Config) Driver() driver.Driver { return &MySQLDriver{} } diff --git a/driver_go110.go b/driver_go110.go index 5389e3107..4b2eff96d 100644 --- a/driver_go110.go +++ b/driver_go110.go @@ -21,7 +21,5 @@ func (d MySQLDriver) OpenConnector(dsn string) (driver.Connector, error) { return nil, err } - return Connector{ - Config: c, - }, nil + return c, nil } From cfaf043ea7a44f589a7501ccbc267187b312291b Mon Sep 17 00:00:00 2001 From: Ichinose Shogo <shogo82148@gmail.com> Date: Sat, 16 Jun 2018 19:15:52 +0900 Subject: [PATCH 06/14] rename driver_go110.go --- driver_go110.go => driver_go1.10.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) rename driver_go110.go => driver_go1.10.go (86%) diff --git a/driver_go110.go b/driver_go1.10.go similarity index 86% rename from driver_go110.go rename to driver_go1.10.go index 4b2eff96d..ef3392dc0 100644 --- a/driver_go110.go +++ b/driver_go1.10.go @@ -1,13 +1,11 @@ // Go MySQL Driver - A MySQL-Driver for Go's database/sql package // -// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. +// Copyright 2018 The Go-MySQL-Driver Authors. All rights reserved. // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at http://mozilla.org/MPL/2.0/. -// +build go1.10 - package mysql import ( From 49e248029a3ed1958a80ae7dfd199851e0447652 Mon Sep 17 00:00:00 2001 From: Ichinose Shogo <shogo82148@gmail.com> Date: Sat, 16 Jun 2018 19:31:12 +0900 Subject: [PATCH 07/14] fix broken build. --- connector_go1.10.go => connector_go1.8.go | 19 ++++++++++++++++--- driver_go1.10.go | 2 ++ driver_go1.10_test.go | 2 ++ 3 files changed, 20 insertions(+), 3 deletions(-) rename connector_go1.10.go => connector_go1.8.go (82%) diff --git a/connector_go1.10.go b/connector_go1.8.go similarity index 82% rename from connector_go1.10.go rename to connector_go1.8.go index 90b1a86d6..a74642e80 100644 --- a/connector_go1.10.go +++ b/connector_go1.8.go @@ -6,6 +6,8 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at http://mozilla.org/MPL/2.0/. +// +build go1.8 + package mysql import ( @@ -67,20 +69,31 @@ func (c *Config) Connect(ctx context.Context) (driver.Conn, error) { mc.writeTimeout = mc.cfg.WriteTimeout // Reading Handshake Initialization Packet - cipher, err := mc.readInitPacket() + authData, plugin, err := mc.readHandshakePacket() if err != nil { mc.cleanup() return nil, err } // Send Client Authentication Packet - if err = mc.writeAuthPacket(cipher); err != nil { + authResp, addNUL, err := mc.auth(authData, plugin) + if err != nil { + // try the default auth plugin, if using the requested plugin failed + errLog.Print("could not use requested auth plugin '"+plugin+"': ", err.Error()) + plugin = defaultAuthPlugin + authResp, addNUL, err = mc.auth(authData, plugin) + if err != nil { + mc.cleanup() + return nil, err + } + } + if err = mc.writeHandshakeResponsePacket(authResp, addNUL, plugin); err != nil { mc.cleanup() return nil, err } // Handle response to auth packet, switch methods if possible - if err = handleAuthResult(mc, cipher); err != nil { + if err = mc.handleAuthResult(authData, plugin); err != nil { // Authentication failed and MySQL has already closed the connection // (https://dev.mysql.com/doc/internals/en/authentication-fails.html). // Do not send COM_QUIT, just cleanup and return the error. diff --git a/driver_go1.10.go b/driver_go1.10.go index ef3392dc0..2008df7a6 100644 --- a/driver_go1.10.go +++ b/driver_go1.10.go @@ -6,6 +6,8 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at http://mozilla.org/MPL/2.0/. +// +build go1.10 + package mysql import ( diff --git a/driver_go1.10_test.go b/driver_go1.10_test.go index 7641e4b61..a9d784c52 100644 --- a/driver_go1.10_test.go +++ b/driver_go1.10_test.go @@ -6,6 +6,8 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at http://mozilla.org/MPL/2.0/. +// +build go1.10 + package mysql import ( From 82898e3c84ecb5c9618fa16a3264c5e897854083 Mon Sep 17 00:00:00 2001 From: Ichinose Shogo <shogo82148@gmail.com> Date: Sat, 16 Jun 2018 20:04:25 +0900 Subject: [PATCH 08/14] simplify OpenConnector --- driver_go1.10.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/driver_go1.10.go b/driver_go1.10.go index 2008df7a6..11b863a11 100644 --- a/driver_go1.10.go +++ b/driver_go1.10.go @@ -16,10 +16,5 @@ import ( // OpenConnector implements driver.DriverContext. func (d MySQLDriver) OpenConnector(dsn string) (driver.Connector, error) { - c, err := ParseDSN(dsn) - if err != nil { - return nil, err - } - - return c, nil + return ParseDSN(dsn) } From ee66ae64098e2c98654d22574e54c3f278e3bed0 Mon Sep 17 00:00:00 2001 From: Ichinose Shogo <shogo82148@gmail.com> Date: Sat, 16 Jun 2018 20:15:04 +0900 Subject: [PATCH 09/14] make `MySQLDriver.Open` more simple. --- connector_go1.8.go => connector.go | 6 +- driver.go | 105 +---------------------------- 2 files changed, 6 insertions(+), 105 deletions(-) rename connector_go1.8.go => connector.go (98%) diff --git a/connector_go1.8.go b/connector.go similarity index 98% rename from connector_go1.8.go rename to connector.go index a74642e80..89c6cf7f0 100644 --- a/connector_go1.8.go +++ b/connector.go @@ -6,8 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at http://mozilla.org/MPL/2.0/. -// +build go1.8 - package mysql import ( @@ -56,7 +54,9 @@ func (c *Config) Connect(ctx context.Context) (driver.Conn, error) { } // Call startWatcher for context support (From Go 1.8) - mc.startWatcher() + if s, ok := interface{}(mc).(watcher); ok { + s.startWatcher() + } if err := mc.watchCancel(ctx); err != nil { return nil, err } diff --git a/driver.go b/driver.go index 1a75a16ec..b6063fef4 100644 --- a/driver.go +++ b/driver.go @@ -17,6 +17,7 @@ package mysql import ( + "context" "database/sql" "database/sql/driver" "net" @@ -57,111 +58,11 @@ func RegisterDial(net string, dial DialFunc) { // See https://github.com/go-sql-driver/mysql#dsn-data-source-name for how // the DSN string is formated func (d MySQLDriver) Open(dsn string) (driver.Conn, error) { - var err error - - // New mysqlConn - mc := &mysqlConn{ - maxAllowedPacket: maxPacketSize, - maxWriteSize: maxPacketSize - 1, - closech: make(chan struct{}), - } - mc.cfg, err = ParseDSN(dsn) - if err != nil { - return nil, err - } - mc.parseTime = mc.cfg.ParseTime - - // Connect to Server - dialsLock.RLock() - dial, ok := dials[mc.cfg.Net] - dialsLock.RUnlock() - if ok { - mc.netConn, err = dial(mc.cfg.Addr) - } else { - nd := net.Dialer{Timeout: mc.cfg.Timeout} - mc.netConn, err = nd.Dial(mc.cfg.Net, mc.cfg.Addr) - } - if err != nil { - return nil, err - } - - // Enable TCP Keepalives on TCP connections - if tc, ok := mc.netConn.(*net.TCPConn); ok { - if err := tc.SetKeepAlive(true); err != nil { - // Don't send COM_QUIT before handshake. - mc.netConn.Close() - mc.netConn = nil - return nil, err - } - } - - // Call startWatcher for context support (From Go 1.8) - if s, ok := interface{}(mc).(watcher); ok { - s.startWatcher() - } - - mc.buf = newBuffer(mc.netConn) - - // Set I/O timeouts - mc.buf.timeout = mc.cfg.ReadTimeout - mc.writeTimeout = mc.cfg.WriteTimeout - - // Reading Handshake Initialization Packet - authData, plugin, err := mc.readHandshakePacket() + c, err := ParseDSN(dsn) if err != nil { - mc.cleanup() return nil, err } - - // Send Client Authentication Packet - authResp, addNUL, err := mc.auth(authData, plugin) - if err != nil { - // try the default auth plugin, if using the requested plugin failed - errLog.Print("could not use requested auth plugin '"+plugin+"': ", err.Error()) - plugin = defaultAuthPlugin - authResp, addNUL, err = mc.auth(authData, plugin) - if err != nil { - mc.cleanup() - return nil, err - } - } - if err = mc.writeHandshakeResponsePacket(authResp, addNUL, plugin); err != nil { - mc.cleanup() - return nil, err - } - - // Handle response to auth packet, switch methods if possible - if err = mc.handleAuthResult(authData, plugin); err != nil { - // Authentication failed and MySQL has already closed the connection - // (https://dev.mysql.com/doc/internals/en/authentication-fails.html). - // Do not send COM_QUIT, just cleanup and return the error. - mc.cleanup() - return nil, err - } - - if mc.cfg.MaxAllowedPacket > 0 { - mc.maxAllowedPacket = mc.cfg.MaxAllowedPacket - } else { - // Get max allowed packet size - maxap, err := mc.getSystemVar("max_allowed_packet") - if err != nil { - mc.Close() - return nil, err - } - mc.maxAllowedPacket = stringToInt(maxap) - 1 - } - if mc.maxAllowedPacket < maxPacketSize { - mc.maxWriteSize = mc.maxAllowedPacket - } - - // Handle DSN Params - err = mc.handleParams() - if err != nil { - mc.Close() - return nil, err - } - - return mc, nil + return c.Connect(context.Background()) } func init() { From 069b52996568a9c28916402d41ccc5f03399a3af Mon Sep 17 00:00:00 2001 From: Ichinose Shogo <shogo82148@gmail.com> Date: Sat, 16 Jun 2018 20:23:56 +0900 Subject: [PATCH 10/14] fix broken build with Go 1.7 --- connector.go | 8 ++++---- driver.go | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/connector.go b/connector.go index 89c6cf7f0..daa180734 100644 --- a/connector.go +++ b/connector.go @@ -56,11 +56,11 @@ func (c *Config) Connect(ctx context.Context) (driver.Conn, error) { // Call startWatcher for context support (From Go 1.8) if s, ok := interface{}(mc).(watcher); ok { s.startWatcher() + if err := s.watchCancel(ctx); err != nil { + return nil, err + } + defer mc.finish() } - if err := mc.watchCancel(ctx); err != nil { - return nil, err - } - defer mc.finish() mc.buf = newBuffer(mc.netConn) diff --git a/driver.go b/driver.go index b6063fef4..7739ab584 100644 --- a/driver.go +++ b/driver.go @@ -27,6 +27,7 @@ import ( // watcher interface is used for context support (From Go 1.8) type watcher interface { startWatcher() + watchCancel(ctx context.Context) error } // MySQLDriver is exported to make the driver directly accessible. From d081e4e80200d1bdfffe0c737789ebd2e18d2384 Mon Sep 17 00:00:00 2001 From: Ichinose Shogo <shogo82148@gmail.com> Date: Wed, 20 Jun 2018 09:21:02 +0900 Subject: [PATCH 11/14] remove the watcher interface --- connector.go | 10 ++++------ driver.go | 6 ------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/connector.go b/connector.go index daa180734..a7d5b3f3f 100644 --- a/connector.go +++ b/connector.go @@ -54,13 +54,11 @@ func (c *Config) Connect(ctx context.Context) (driver.Conn, error) { } // Call startWatcher for context support (From Go 1.8) - if s, ok := interface{}(mc).(watcher); ok { - s.startWatcher() - if err := s.watchCancel(ctx); err != nil { - return nil, err - } - defer mc.finish() + mc.startWatcher() + if err := mc.watchCancel(ctx); err != nil { + return nil, err } + defer mc.finish() mc.buf = newBuffer(mc.netConn) diff --git a/driver.go b/driver.go index 7739ab584..9f1e486cb 100644 --- a/driver.go +++ b/driver.go @@ -24,12 +24,6 @@ import ( "sync" ) -// watcher interface is used for context support (From Go 1.8) -type watcher interface { - startWatcher() - watchCancel(ctx context.Context) error -} - // MySQLDriver is exported to make the driver directly accessible. // In general the driver is used via the database/sql package. type MySQLDriver struct{} From 40d78d5360212fe55f0c0807acc20c99c48a98a1 Mon Sep 17 00:00:00 2001 From: Ichinose Shogo <shogo82148@gmail.com> Date: Mon, 29 Oct 2018 00:14:59 +0900 Subject: [PATCH 12/14] apply the chages of 7ac0064e --- connector.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/connector.go b/connector.go index a7d5b3f3f..e4fd76f63 100644 --- a/connector.go +++ b/connector.go @@ -73,6 +73,10 @@ func (c *Config) Connect(ctx context.Context) (driver.Conn, error) { return nil, err } + if plugin == "" { + plugin = defaultAuthPlugin + } + // Send Client Authentication Packet authResp, addNUL, err := mc.auth(authData, plugin) if err != nil { From 1b00bed8a76846fdd80bea1dd2d649448aa1cfdc Mon Sep 17 00:00:00 2001 From: Ichinose Shogo <shogo82148@gmail.com> Date: Tue, 30 Oct 2018 08:23:46 +0900 Subject: [PATCH 13/14] add the connetor struct --- connector.go | 10 +++++++--- driver.go | 5 ++++- driver_go1.10.go | 8 +++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/connector.go b/connector.go index e4fd76f63..876ad976d 100644 --- a/connector.go +++ b/connector.go @@ -14,9 +14,13 @@ import ( "net" ) +type connector struct { + cfg *Config // immutable private copy. +} + // Connect implements driver.Connector interface. // Connect returns a connection to the database. -func (c *Config) Connect(ctx context.Context) (driver.Conn, error) { +func (c *connector) Connect(ctx context.Context) (driver.Conn, error) { var err error // New mysqlConn @@ -24,7 +28,7 @@ func (c *Config) Connect(ctx context.Context) (driver.Conn, error) { maxAllowedPacket: maxPacketSize, maxWriteSize: maxPacketSize - 1, closech: make(chan struct{}), - cfg: c, + cfg: c.cfg, } mc.parseTime = mc.cfg.ParseTime @@ -130,6 +134,6 @@ func (c *Config) Connect(ctx context.Context) (driver.Conn, error) { // Driver implements driver.Connector interface. // Driver returns &MySQLDriver{}. -func (c *Config) Driver() driver.Driver { +func (c *connector) Driver() driver.Driver { return &MySQLDriver{} } diff --git a/driver.go b/driver.go index 9f1e486cb..c986f1052 100644 --- a/driver.go +++ b/driver.go @@ -53,10 +53,13 @@ func RegisterDial(net string, dial DialFunc) { // See https://github.com/go-sql-driver/mysql#dsn-data-source-name for how // the DSN string is formated func (d MySQLDriver) Open(dsn string) (driver.Conn, error) { - c, err := ParseDSN(dsn) + cfg, err := ParseDSN(dsn) if err != nil { return nil, err } + c := &connector{ + cfg: cfg, + } return c.Connect(context.Background()) } diff --git a/driver_go1.10.go b/driver_go1.10.go index 11b863a11..9669a4f01 100644 --- a/driver_go1.10.go +++ b/driver_go1.10.go @@ -16,5 +16,11 @@ import ( // OpenConnector implements driver.DriverContext. func (d MySQLDriver) OpenConnector(dsn string) (driver.Connector, error) { - return ParseDSN(dsn) + cfg, err := ParseDSN(dsn) + if err != nil { + return nil, err + } + return &connector{ + cfg: cfg, + }, nil } From 255f9886a5b8e006949d618de10bba07f6055722 Mon Sep 17 00:00:00 2001 From: Ichinose Shogo <shogo82148@gmail.com> Date: Tue, 30 Oct 2018 08:41:14 +0900 Subject: [PATCH 14/14] add NewConnector --- driver_go1.10.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/driver_go1.10.go b/driver_go1.10.go index 9669a4f01..b0ee134bd 100644 --- a/driver_go1.10.go +++ b/driver_go1.10.go @@ -11,9 +11,28 @@ package mysql import ( + "crypto/rsa" "database/sql/driver" + "math/big" ) +// NewConnector returns new driver.Connector. +func NewConnector(cfg *Config) driver.Connector { + copyCfg := *cfg + copyCfg.tls = cfg.tls.Clone() + copyCfg.Params = make(map[string]string, len(cfg.Params)) + for k, v := range cfg.Params { + copyCfg.Params[k] = v + } + if cfg.pubKey != nil { + copyCfg.pubKey = &rsa.PublicKey{ + N: new(big.Int).Set(cfg.pubKey.N), + E: cfg.pubKey.E, + } + } + return &connector{cfg: ©Cfg} +} + // OpenConnector implements driver.DriverContext. func (d MySQLDriver) OpenConnector(dsn string) (driver.Connector, error) { cfg, err := ParseDSN(dsn)