Skip to content

Commit 1edf8de

Browse files
committed
Revert "Remove "go1.10" build tag (go-sql-driver#1016)"
This reverts commit b66d043.
1 parent b66d043 commit 1edf8de

File tree

5 files changed

+227
-192
lines changed

5 files changed

+227
-192
lines changed

AUTHORS

-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ Lucas Liu <extrafliu at gmail.com>
6363
Luke Scott <luke at webconnex.com>
6464
Maciej Zimnoch <maciej.zimnoch at codilime.com>
6565
Michael Woolnough <michael.woolnough at gmail.com>
66-
Nathanial Murphy <nathanial.murphy at gmail.com>
6766
Nicola Peduzzi <thenikso at gmail.com>
6867
Olivier Mengué <dolmen at cpan.org>
6968
oscarzhao <oscarzhaosl at gmail.com>

driver.go

-22
Original file line numberDiff line numberDiff line change
@@ -83,25 +83,3 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
8383
func init() {
8484
sql.Register("mysql", &MySQLDriver{})
8585
}
86-
87-
// NewConnector returns new driver.Connector.
88-
func NewConnector(cfg *Config) (driver.Connector, error) {
89-
cfg = cfg.Clone()
90-
// normalize the contents of cfg so calls to NewConnector have the same
91-
// behavior as MySQLDriver.OpenConnector
92-
if err := cfg.normalize(); err != nil {
93-
return nil, err
94-
}
95-
return &connector{cfg: cfg}, nil
96-
}
97-
98-
// OpenConnector implements driver.DriverContext.
99-
func (d MySQLDriver) OpenConnector(dsn string) (driver.Connector, error) {
100-
cfg, err := ParseDSN(dsn)
101-
if err != nil {
102-
return nil, err
103-
}
104-
return &connector{
105-
cfg: cfg,
106-
}, nil
107-
}

driver_go110.go

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
2+
//
3+
// Copyright 2018 The Go-MySQL-Driver Authors. All rights reserved.
4+
//
5+
// This Source Code Form is subject to the terms of the Mozilla Public
6+
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
7+
// You can obtain one at http://mozilla.org/MPL/2.0/.
8+
9+
// +build go1.10
10+
11+
package mysql
12+
13+
import (
14+
"database/sql/driver"
15+
)
16+
17+
// NewConnector returns new driver.Connector.
18+
func NewConnector(cfg *Config) (driver.Connector, error) {
19+
cfg = cfg.Clone()
20+
// normalize the contents of cfg so calls to NewConnector have the same
21+
// behavior as MySQLDriver.OpenConnector
22+
if err := cfg.normalize(); err != nil {
23+
return nil, err
24+
}
25+
return &connector{cfg: cfg}, nil
26+
}
27+
28+
// OpenConnector implements driver.DriverContext.
29+
func (d MySQLDriver) OpenConnector(dsn string) (driver.Connector, error) {
30+
cfg, err := ParseDSN(dsn)
31+
if err != nil {
32+
return nil, err
33+
}
34+
return &connector{
35+
cfg: cfg,
36+
}, nil
37+
}

driver_go110_test.go

+190
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
2+
//
3+
// Copyright 2018 The Go-MySQL-Driver Authors. All rights reserved.
4+
//
5+
// This Source Code Form is subject to the terms of the Mozilla Public
6+
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
7+
// You can obtain one at http://mozilla.org/MPL/2.0/.
8+
9+
// +build go1.10
10+
11+
package mysql
12+
13+
import (
14+
"context"
15+
"database/sql"
16+
"database/sql/driver"
17+
"fmt"
18+
"net"
19+
"testing"
20+
"time"
21+
)
22+
23+
var _ driver.DriverContext = &MySQLDriver{}
24+
25+
type dialCtxKey struct{}
26+
27+
func TestConnectorObeysDialTimeouts(t *testing.T) {
28+
if !available {
29+
t.Skipf("MySQL server not running on %s", netAddr)
30+
}
31+
32+
RegisterDialContext("dialctxtest", func(ctx context.Context, addr string) (net.Conn, error) {
33+
var d net.Dialer
34+
if !ctx.Value(dialCtxKey{}).(bool) {
35+
return nil, fmt.Errorf("test error: query context is not propagated to our dialer")
36+
}
37+
return d.DialContext(ctx, prot, addr)
38+
})
39+
40+
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@dialctxtest(%s)/%s?timeout=30s", user, pass, addr, dbname))
41+
if err != nil {
42+
t.Fatalf("error connecting: %s", err.Error())
43+
}
44+
defer db.Close()
45+
46+
ctx := context.WithValue(context.Background(), dialCtxKey{}, true)
47+
48+
_, err = db.ExecContext(ctx, "DO 1")
49+
if err != nil {
50+
t.Fatal(err)
51+
}
52+
}
53+
54+
func configForTests(t *testing.T) *Config {
55+
if !available {
56+
t.Skipf("MySQL server not running on %s", netAddr)
57+
}
58+
59+
mycnf := NewConfig()
60+
mycnf.User = user
61+
mycnf.Passwd = pass
62+
mycnf.Addr = addr
63+
mycnf.Net = prot
64+
mycnf.DBName = dbname
65+
return mycnf
66+
}
67+
68+
func TestNewConnector(t *testing.T) {
69+
mycnf := configForTests(t)
70+
conn, err := NewConnector(mycnf)
71+
if err != nil {
72+
t.Fatal(err)
73+
}
74+
75+
db := sql.OpenDB(conn)
76+
defer db.Close()
77+
78+
if err := db.Ping(); err != nil {
79+
t.Fatal(err)
80+
}
81+
}
82+
83+
type slowConnection struct {
84+
net.Conn
85+
slowdown time.Duration
86+
}
87+
88+
func (sc *slowConnection) Read(b []byte) (int, error) {
89+
time.Sleep(sc.slowdown)
90+
return sc.Conn.Read(b)
91+
}
92+
93+
type connectorHijack struct {
94+
driver.Connector
95+
connErr error
96+
}
97+
98+
func (cw *connectorHijack) Connect(ctx context.Context) (driver.Conn, error) {
99+
var conn driver.Conn
100+
conn, cw.connErr = cw.Connector.Connect(ctx)
101+
return conn, cw.connErr
102+
}
103+
104+
func TestConnectorTimeoutsDuringOpen(t *testing.T) {
105+
RegisterDialContext("slowconn", func(ctx context.Context, addr string) (net.Conn, error) {
106+
var d net.Dialer
107+
conn, err := d.DialContext(ctx, prot, addr)
108+
if err != nil {
109+
return nil, err
110+
}
111+
return &slowConnection{Conn: conn, slowdown: 100 * time.Millisecond}, nil
112+
})
113+
114+
mycnf := configForTests(t)
115+
mycnf.Net = "slowconn"
116+
117+
conn, err := NewConnector(mycnf)
118+
if err != nil {
119+
t.Fatal(err)
120+
}
121+
122+
hijack := &connectorHijack{Connector: conn}
123+
124+
db := sql.OpenDB(hijack)
125+
defer db.Close()
126+
127+
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
128+
defer cancel()
129+
130+
_, err = db.ExecContext(ctx, "DO 1")
131+
if err != context.DeadlineExceeded {
132+
t.Fatalf("ExecContext should have timed out")
133+
}
134+
if hijack.connErr != context.DeadlineExceeded {
135+
t.Fatalf("(*Connector).Connect should have timed out")
136+
}
137+
}
138+
139+
// A connection which can only be closed.
140+
type dummyConnection struct {
141+
net.Conn
142+
closed bool
143+
}
144+
145+
func (d *dummyConnection) Close() error {
146+
d.closed = true
147+
return nil
148+
}
149+
150+
func TestConnectorTimeoutsWatchCancel(t *testing.T) {
151+
var (
152+
cancel func() // Used to cancel the context just after connecting.
153+
created *dummyConnection // The created connection.
154+
)
155+
156+
RegisterDialContext("TestConnectorTimeoutsWatchCancel", func(ctx context.Context, addr string) (net.Conn, error) {
157+
// Canceling at this time triggers the watchCancel error branch in Connect().
158+
cancel()
159+
created = &dummyConnection{}
160+
return created, nil
161+
})
162+
163+
mycnf := NewConfig()
164+
mycnf.User = "root"
165+
mycnf.Addr = "foo"
166+
mycnf.Net = "TestConnectorTimeoutsWatchCancel"
167+
168+
conn, err := NewConnector(mycnf)
169+
if err != nil {
170+
t.Fatal(err)
171+
}
172+
173+
db := sql.OpenDB(conn)
174+
defer db.Close()
175+
176+
var ctx context.Context
177+
ctx, cancel = context.WithCancel(context.Background())
178+
defer cancel()
179+
180+
if _, err := db.Conn(ctx); err != context.Canceled {
181+
t.Errorf("got %v, want context.Canceled", err)
182+
}
183+
184+
if created == nil {
185+
t.Fatal("no connection created")
186+
}
187+
if !created.closed {
188+
t.Errorf("connection not closed")
189+
}
190+
}

0 commit comments

Comments
 (0)