upgrade go-sql-driver/mysql to fix invalid connection error (#5748)
should fix #5736tokarchuk/v1.17
parent
5ac6da3c41
commit
477a80f658
@ -1,208 +0,0 @@ |
||||
// 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.8
|
||||
|
||||
package mysql |
||||
|
||||
import ( |
||||
"context" |
||||
"database/sql" |
||||
"database/sql/driver" |
||||
) |
||||
|
||||
// Ping implements driver.Pinger interface
|
||||
func (mc *mysqlConn) Ping(ctx context.Context) (err error) { |
||||
if mc.closed.IsSet() { |
||||
errLog.Print(ErrInvalidConn) |
||||
return driver.ErrBadConn |
||||
} |
||||
|
||||
if err = mc.watchCancel(ctx); err != nil { |
||||
return |
||||
} |
||||
defer mc.finish() |
||||
|
||||
if err = mc.writeCommandPacket(comPing); err != nil { |
||||
return |
||||
} |
||||
|
||||
return mc.readResultOK() |
||||
} |
||||
|
||||
// BeginTx implements driver.ConnBeginTx interface
|
||||
func (mc *mysqlConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) { |
||||
if err := mc.watchCancel(ctx); err != nil { |
||||
return nil, err |
||||
} |
||||
defer mc.finish() |
||||
|
||||
if sql.IsolationLevel(opts.Isolation) != sql.LevelDefault { |
||||
level, err := mapIsolationLevel(opts.Isolation) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
err = mc.exec("SET TRANSACTION ISOLATION LEVEL " + level) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
} |
||||
|
||||
return mc.begin(opts.ReadOnly) |
||||
} |
||||
|
||||
func (mc *mysqlConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) { |
||||
dargs, err := namedValueToValue(args) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
if err := mc.watchCancel(ctx); err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
rows, err := mc.query(query, dargs) |
||||
if err != nil { |
||||
mc.finish() |
||||
return nil, err |
||||
} |
||||
rows.finish = mc.finish |
||||
return rows, err |
||||
} |
||||
|
||||
func (mc *mysqlConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) { |
||||
dargs, err := namedValueToValue(args) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
if err := mc.watchCancel(ctx); err != nil { |
||||
return nil, err |
||||
} |
||||
defer mc.finish() |
||||
|
||||
return mc.Exec(query, dargs) |
||||
} |
||||
|
||||
func (mc *mysqlConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) { |
||||
if err := mc.watchCancel(ctx); err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
stmt, err := mc.Prepare(query) |
||||
mc.finish() |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
select { |
||||
default: |
||||
case <-ctx.Done(): |
||||
stmt.Close() |
||||
return nil, ctx.Err() |
||||
} |
||||
return stmt, nil |
||||
} |
||||
|
||||
func (stmt *mysqlStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) { |
||||
dargs, err := namedValueToValue(args) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
if err := stmt.mc.watchCancel(ctx); err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
rows, err := stmt.query(dargs) |
||||
if err != nil { |
||||
stmt.mc.finish() |
||||
return nil, err |
||||
} |
||||
rows.finish = stmt.mc.finish |
||||
return rows, err |
||||
} |
||||
|
||||
func (stmt *mysqlStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) { |
||||
dargs, err := namedValueToValue(args) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
if err := stmt.mc.watchCancel(ctx); err != nil { |
||||
return nil, err |
||||
} |
||||
defer stmt.mc.finish() |
||||
|
||||
return stmt.Exec(dargs) |
||||
} |
||||
|
||||
func (mc *mysqlConn) watchCancel(ctx context.Context) error { |
||||
if mc.watching { |
||||
// Reach here if canceled,
|
||||
// so the connection is already invalid
|
||||
mc.cleanup() |
||||
return nil |
||||
} |
||||
if ctx.Done() == nil { |
||||
return nil |
||||
} |
||||
|
||||
mc.watching = true |
||||
select { |
||||
default: |
||||
case <-ctx.Done(): |
||||
return ctx.Err() |
||||
} |
||||
if mc.watcher == nil { |
||||
return nil |
||||
} |
||||
|
||||
mc.watcher <- ctx |
||||
|
||||
return nil |
||||
} |
||||
|
||||
func (mc *mysqlConn) startWatcher() { |
||||
watcher := make(chan mysqlContext, 1) |
||||
mc.watcher = watcher |
||||
finished := make(chan struct{}) |
||||
mc.finished = finished |
||||
go func() { |
||||
for { |
||||
var ctx mysqlContext |
||||
select { |
||||
case ctx = <-watcher: |
||||
case <-mc.closech: |
||||
return |
||||
} |
||||
|
||||
select { |
||||
case <-ctx.Done(): |
||||
mc.cancel(ctx.Err()) |
||||
case <-finished: |
||||
case <-mc.closech: |
||||
return |
||||
} |
||||
} |
||||
}() |
||||
} |
||||
|
||||
func (mc *mysqlConn) CheckNamedValue(nv *driver.NamedValue) (err error) { |
||||
nv.Value, err = converter{}.ConvertValue(nv.Value) |
||||
return |
||||
} |
||||
|
||||
// ResetSession implements driver.SessionResetter.
|
||||
// (From Go 1.10)
|
||||
func (mc *mysqlConn) ResetSession(ctx context.Context) error { |
||||
if mc.closed.IsSet() { |
||||
return driver.ErrBadConn |
||||
} |
||||
return nil |
||||
} |
@ -1,40 +0,0 @@ |
||||
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
|
||||
//
|
||||
// Copyright 2017 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.7
|
||||
// +build !go1.8
|
||||
|
||||
package mysql |
||||
|
||||
import "crypto/tls" |
||||
|
||||
func cloneTLSConfig(c *tls.Config) *tls.Config { |
||||
return &tls.Config{ |
||||
Rand: c.Rand, |
||||
Time: c.Time, |
||||
Certificates: c.Certificates, |
||||
NameToCertificate: c.NameToCertificate, |
||||
GetCertificate: c.GetCertificate, |
||||
RootCAs: c.RootCAs, |
||||
NextProtos: c.NextProtos, |
||||
ServerName: c.ServerName, |
||||
ClientAuth: c.ClientAuth, |
||||
ClientCAs: c.ClientCAs, |
||||
InsecureSkipVerify: c.InsecureSkipVerify, |
||||
CipherSuites: c.CipherSuites, |
||||
PreferServerCipherSuites: c.PreferServerCipherSuites, |
||||
SessionTicketsDisabled: c.SessionTicketsDisabled, |
||||
SessionTicketKey: c.SessionTicketKey, |
||||
ClientSessionCache: c.ClientSessionCache, |
||||
MinVersion: c.MinVersion, |
||||
MaxVersion: c.MaxVersion, |
||||
CurvePreferences: c.CurvePreferences, |
||||
DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, |
||||
Renegotiation: c.Renegotiation, |
||||
} |
||||
} |
@ -1,50 +0,0 @@ |
||||
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
|
||||
//
|
||||
// Copyright 2017 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.8
|
||||
|
||||
package mysql |
||||
|
||||
import ( |
||||
"crypto/tls" |
||||
"database/sql" |
||||
"database/sql/driver" |
||||
"errors" |
||||
"fmt" |
||||
) |
||||
|
||||
func cloneTLSConfig(c *tls.Config) *tls.Config { |
||||
return c.Clone() |
||||
} |
||||
|
||||
func namedValueToValue(named []driver.NamedValue) ([]driver.Value, error) { |
||||
dargs := make([]driver.Value, len(named)) |
||||
for n, param := range named { |
||||
if len(param.Name) > 0 { |
||||
// TODO: support the use of Named Parameters #561
|
||||
return nil, errors.New("mysql: driver does not support the use of Named Parameters") |
||||
} |
||||
dargs[n] = param.Value |
||||
} |
||||
return dargs, nil |
||||
} |
||||
|
||||
func mapIsolationLevel(level driver.IsolationLevel) (string, error) { |
||||
switch sql.IsolationLevel(level) { |
||||
case sql.LevelRepeatableRead: |
||||
return "REPEATABLE READ", nil |
||||
case sql.LevelReadCommitted: |
||||
return "READ COMMITTED", nil |
||||
case sql.LevelReadUncommitted: |
||||
return "READ UNCOMMITTED", nil |
||||
case sql.LevelSerializable: |
||||
return "SERIALIZABLE", nil |
||||
default: |
||||
return "", fmt.Errorf("mysql: unsupported isolation level: %v", level) |
||||
} |
||||
} |
Loading…
Reference in new issue