17
17
package mysql
18
18
19
19
import (
20
+ "context"
20
21
"database/sql"
21
22
"database/sql/driver"
23
+ "errors"
22
24
"net"
23
25
)
24
26
27
+ var (
28
+ errInvalidUser = errors .New ("invalid Connection: User is not set or longer than 32 chars" )
29
+ errInvalidAddr = errors .New ("invalid Connection: Addr config is missing" )
30
+ errInvalidNet = errors .New ("invalid Connection: Only tcp is valid for Net" )
31
+ errInvalidDBName = errors .New ("invalid Connection: DBName config is missing" )
32
+ )
33
+
25
34
// watcher interface is used for context support (From Go 1.8)
26
35
type watcher interface {
27
36
startWatcher ()
28
37
}
29
38
30
39
// MySQLDriver is exported to make the driver directly accessible.
31
40
// In general the driver is used via the database/sql package.
32
- type MySQLDriver struct {}
41
+ type MySQLDriver struct {
42
+ Cfg * Config
43
+ }
33
44
34
45
// DialFunc is a function which can be used to establish the network connection.
35
46
// Custom dial functions must be registered with RegisterDial
@@ -47,24 +58,9 @@ func RegisterDial(net string, dial DialFunc) {
47
58
dials [net ] = dial
48
59
}
49
60
50
- // Open new Connection.
51
- // See https://github.com/go-sql-driver/mysql#dsn-data-source-name for how
52
- // the DSN string is formated
53
- func (d MySQLDriver ) Open (dsn string ) (driver.Conn , error ) {
61
+ //Open a new Connection
62
+ func (d MySQLDriver ) connectServer (mc * mysqlConn ) error {
54
63
var err error
55
-
56
- // New mysqlConn
57
- mc := & mysqlConn {
58
- maxAllowedPacket : maxPacketSize ,
59
- maxWriteSize : maxPacketSize - 1 ,
60
- closech : make (chan struct {}),
61
- }
62
- mc .cfg , err = ParseDSN (dsn )
63
- if err != nil {
64
- return nil , err
65
- }
66
- mc .parseTime = mc .cfg .ParseTime
67
-
68
64
// Connect to Server
69
65
if dial , ok := dials [mc .cfg .Net ]; ok {
70
66
mc .netConn , err = dial (mc .cfg .Addr )
@@ -73,7 +69,7 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
73
69
mc .netConn , err = nd .Dial (mc .cfg .Net , mc .cfg .Addr )
74
70
}
75
71
if err != nil {
76
- return nil , err
72
+ return err
77
73
}
78
74
79
75
// Enable TCP Keepalives on TCP connections
@@ -82,7 +78,7 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
82
78
// Don't send COM_QUIT before handshake.
83
79
mc .netConn .Close ()
84
80
mc .netConn = nil
85
- return nil , err
81
+ return err
86
82
}
87
83
}
88
84
@@ -101,13 +97,13 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
101
97
cipher , err := mc .readInitPacket ()
102
98
if err != nil {
103
99
mc .cleanup ()
104
- return nil , err
100
+ return err
105
101
}
106
102
107
103
// Send Client Authentication Packet
108
104
if err = mc .writeAuthPacket (cipher ); err != nil {
109
105
mc .cleanup ()
110
- return nil , err
106
+ return err
111
107
}
112
108
113
109
// Handle response to auth packet, switch methods if possible
@@ -116,7 +112,7 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
116
112
// (https://dev.mysql.com/doc/internals/en/authentication-fails.html).
117
113
// Do not send COM_QUIT, just cleanup and return the error.
118
114
mc .cleanup ()
119
- return nil , err
115
+ return err
120
116
}
121
117
122
118
if mc .cfg .MaxAllowedPacket > 0 {
@@ -126,14 +122,90 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
126
122
maxap , err := mc .getSystemVar ("max_allowed_packet" )
127
123
if err != nil {
128
124
mc .Close ()
129
- return nil , err
125
+ return err
130
126
}
131
127
mc .maxAllowedPacket = stringToInt (maxap ) - 1
132
128
}
133
129
if mc .maxAllowedPacket < maxPacketSize {
134
130
mc .maxWriteSize = mc .maxAllowedPacket
135
131
}
136
132
133
+ return err
134
+ }
135
+
136
+ //Connect opens a new connection without using a DSN
137
+ func (d MySQLDriver ) Connect (cxt context.Context ) (driver.Conn , error ) {
138
+ var err error
139
+
140
+ //Validate the connection parameters
141
+ //the following are required User,Pass,Net,Addr,DBName
142
+ //Pass may be blank
143
+ //The other optional parameters are not checks
144
+ //as GO will automatically enforce proper bool types on the options
145
+ if len (d .Cfg .User ) > 32 || len (d .Cfg .User ) <= 0 {
146
+ return nil , errInvalidUser
147
+ }
148
+
149
+ if len (d .Cfg .Addr ) <= 0 {
150
+ return nil , errInvalidAddr
151
+ }
152
+
153
+ if len (d .Cfg .DBName ) <= 0 {
154
+ return nil , errInvalidDBName
155
+ }
156
+
157
+ if d .Cfg .Net != "tcp" {
158
+ return nil , errInvalidNet
159
+ }
160
+
161
+ //New mysqlConn
162
+ mc := & mysqlConn {
163
+ maxAllowedPacket : maxPacketSize ,
164
+ maxWriteSize : maxPacketSize - 1 ,
165
+ closech : make (chan struct {}),
166
+ cfg : d .Cfg ,
167
+ parseTime : d .Cfg .ParseTime ,
168
+ }
169
+
170
+ //Connect to the server and setting the connection settings
171
+ err = d .connectServer (mc )
172
+ if err != nil {
173
+ return nil , err
174
+ }
175
+
176
+ return mc , nil
177
+
178
+ }
179
+
180
+ //Driver returns a driver interface
181
+ func (d MySQLDriver ) Driver () driver.Driver {
182
+ return MySQLDriver {}
183
+ }
184
+
185
+ // Open new Connection using a DSN.
186
+ // See https://github.com/go-sql-driver/mysql#dsn-data-source-name for how
187
+ // the DSN string is formated
188
+ func (d MySQLDriver ) Open (dsn string ) (driver.Conn , error ) {
189
+ var err error
190
+
191
+ // New mysqlConn
192
+ mc := & mysqlConn {
193
+ maxAllowedPacket : maxPacketSize ,
194
+ maxWriteSize : maxPacketSize - 1 ,
195
+ closech : make (chan struct {}),
196
+ }
197
+ mc .cfg , err = ParseDSN (dsn )
198
+ if err != nil {
199
+ return nil , err
200
+ }
201
+ mc .parseTime = mc .cfg .ParseTime
202
+
203
+ err = d .connectServer (mc )
204
+ // Connect to Server
205
+ if err != nil {
206
+ return nil , err
207
+ }
208
+
137
209
// Handle DSN Params
138
210
err = mc .handleParams ()
139
211
if err != nil {
0 commit comments