Skip to content

Commit 009a426

Browse files
committed
Merge branch 'master' of github.com:go-mysql-org/go-mysql into improveExample
2 parents 96a7be7 + 145f684 commit 009a426

30 files changed

+706
-125
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ jobs:
55
test:
66
strategy:
77
matrix:
8-
go: [ 1.16, 1.15 ]
8+
go: [ 1.18, 1.17, 1.16, 1.15 ]
99
name: Tests Go ${{ matrix.go }}
1010
runs-on: ubuntu-18.04
1111

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
### Tag v1.5.0 (2022-04-30)
2+
* Replacing github.com/satori/go.uuid with github.com/google/uuid. [#690](https://github.com/go-mysql-org/go-mysql/pull/690) ([martinhrvn](https://github.com/martinhrvn))
3+
* Fix dump gtid regexp. [#688](https://github.com/go-mysql-org/go-mysql/pull/688) ([yrbb](https://github.com/yrbb))
4+
* Utilise byteSlice as a part of struct to avoid allocations. [#686](https://github.com/go-mysql-org/go-mysql/pull/686) ([moredure](https://github.com/moredure))
5+
* Update bytes_buffer_pool.go. [#685](https://github.com/go-mysql-org/go-mysql/pull/685) ([moredure](https://github.com/moredure))
6+
* Add go1.18 to the test matrix. [#684](https://github.com/go-mysql-org/go-mysql/pull/684) ([moredure](https://github.com/moredure))
7+
* Add 1.17 version into the test matrix. [#683](https://github.com/go-mysql-org/go-mysql/pull/683) ([moredure](https://github.com/moredure))
8+
* Stop using channel for memory pooling. [#682](https://github.com/go-mysql-org/go-mysql/pull/682) ([moredure](https://github.com/moredure))
9+
* Fix TIME value near zero will become zero. [#678](https://github.com/go-mysql-org/go-mysql/pull/678) ([lance6716](https://github.com/lance6716))
10+
* Fixed reading connection attributes on server side. [#676](https://github.com/go-mysql-org/go-mysql/pull/676) ([skoef](https://github.com/skoef))
11+
* Support client connection attributes on the client side. [#675](https://github.com/go-mysql-org/go-mysql/pull/675) ([skoef](https://github.com/skoef))
12+
* Support client connection attributes on the server side. [#672](https://github.com/go-mysql-org/go-mysql/pull/672) ([skoef](https://github.com/skoef))
13+
* Added constants for COM_SET_OPTION. [#670](https://github.com/go-mysql-org/go-mysql/pull/670) ([skoef](https://github.com/skoef))
14+
* Implemented ExecuteMultiple. [#668](https://github.com/go-mysql-org/go-mysql/pull/668) ([skoef](https://github.com/skoef))
15+
* Add MysqlGTIDSet.Add() and Minus() methods. [#667](https://github.com/go-mysql-org/go-mysql/pull/667) ([ostinru](https://github.com/ostinru))
16+
* Enabled ineffassign in golangci. [#666](https://github.com/go-mysql-org/go-mysql/pull/666) ([skoef](https://github.com/skoef))
17+
* Enabled gosimple in golangci. [#665](https://github.com/go-mysql-org/go-mysql/pull/665) ([skoef](https://github.com/skoef))
18+
* Add MysqlGTIDSet.Add() and Minus() methods. [#662](https://github.com/go-mysql-org/go-mysql/pull/662) ([ostinru](https://github.com/ostinru))
19+
* Store json as string in rows events. [#658](https://github.com/go-mysql-org/go-mysql/pull/658) ([D3Hunter](https://github.com/D3Hunter))
20+
* Set slave_uuid and replica_uuid. [#656](https://github.com/go-mysql-org/go-mysql/pull/656) ([lance6716](https://github.com/lance6716))
21+
* Fix malformed packet and a panic. [#655](https://github.com/go-mysql-org/go-mysql/pull/655) ([lance6716](https://github.com/lance6716))
22+
* Fix fetchIndexesViaSqlDB/NewTableFromSqlDB for MySQL 8.0. [#527](https://github.com/go-mysql-org/go-mysql/pull/527) ([RobinGeuze](https://github.com/RobinGeuze))
23+
124
### Tag v1.4.0 (2021-12-15)
225
* Fix that forget to readOK after writing. [#652](https://github.com/go-mysql-org/go-mysql/pull/652) ([lance6716](https://github.com/lance6716))
326
* Packet: memory optimization for reading network packet. [#651](https://github.com/go-mysql-org/go-mysql/pull/651) ([zr-hebo](https://github.com/zr-hebo))

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ A pure go library to handle MySQL network protocol and replication.
99
## How to migrate to this repo
1010
To change the used package in your repo it's enough to add this `replace` directive to your `go.mod`:
1111
```
12-
replace github.com/siddontang/go-mysql => github.com/go-mysql-org/go-mysql v1.4.0
12+
replace github.com/siddontang/go-mysql => github.com/go-mysql-org/go-mysql v1.5.0
1313
```
1414

15-
v1.4.0 - is the last tag in repo, feel free to choose what you want.
15+
v1.5.0 - is the last tag in repo, feel free to choose what you want.
1616

1717
## Changelog
1818
This repo uses [Changelog](CHANGELOG.md).

canal/sync.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import (
88
"github.com/go-mysql-org/go-mysql/mysql"
99
"github.com/go-mysql-org/go-mysql/replication"
1010
"github.com/go-mysql-org/go-mysql/schema"
11+
"github.com/google/uuid"
1112
"github.com/pingcap/errors"
1213
"github.com/pingcap/parser/ast"
13-
uuid "github.com/satori/go.uuid"
1414
"github.com/siddontang/go-log/log"
1515
)
1616

client/auth.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,20 @@ func (c *Conn) genAuthResponse(authData []byte) ([]byte, bool, error) {
139139
}
140140
}
141141

142+
// generate connection attributes data
143+
func (c *Conn) genAttributes() []byte {
144+
if len(c.attributes) == 0 {
145+
return nil
146+
}
147+
148+
attrData := make([]byte, 0)
149+
for k, v := range c.attributes {
150+
attrData = append(attrData, PutLengthEncodedString([]byte(k))...)
151+
attrData = append(attrData, PutLengthEncodedString([]byte(v))...)
152+
}
153+
return append(PutLengthEncodedInt(uint64(len(attrData))), attrData...)
154+
}
155+
142156
// See: http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse
143157
func (c *Conn) writeAuthHandshake() error {
144158
if !authPluginAllowed(c.authPluginName) {
@@ -195,6 +209,12 @@ func (c *Conn) writeAuthHandshake() error {
195209
capability |= CLIENT_CONNECT_WITH_DB
196210
length += len(c.db) + 1
197211
}
212+
// connection attributes
213+
attrData := c.genAttributes()
214+
if len(attrData) > 0 {
215+
capability |= CLIENT_CONNECT_ATTRS
216+
length += len(attrData)
217+
}
198218

199219
data := make([]byte, length+4)
200220

@@ -264,6 +284,12 @@ func (c *Conn) writeAuthHandshake() error {
264284
// Assume native client during response
265285
pos += copy(data[pos:], c.authPluginName)
266286
data[pos] = 0x00
287+
pos++
288+
289+
// connection attributes
290+
if len(attrData) > 0 {
291+
copy(data[pos:], attrData)
292+
}
267293

268294
return c.WritePacket(data)
269295
}

client/auth_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package client
2+
3+
import (
4+
"bytes"
5+
"testing"
6+
7+
"github.com/go-mysql-org/go-mysql/mysql"
8+
)
9+
10+
func TestConnGenAttributes(t *testing.T) {
11+
c := &Conn{
12+
// example data from
13+
// https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse41
14+
attributes: map[string]string{
15+
"_os": "debian6.0",
16+
"_client_name": "libmysql",
17+
"_pid": "22344",
18+
"_client_version": "5.6.6-m9",
19+
"_platform": "x86_64",
20+
"foo": "bar",
21+
},
22+
}
23+
24+
data := c.genAttributes()
25+
26+
// the order of the attributes map cannot be guaranteed so to test the content
27+
// of the attribute data we need to check its partial contents
28+
29+
if len(data) != 98 {
30+
t.Fatalf("unexpected data length, got %d", len(data))
31+
}
32+
if data[0] != 0x61 {
33+
t.Fatalf("unexpected length-encoded int, got %#x", data[0])
34+
}
35+
36+
for k, v := range c.attributes {
37+
fixt := append(mysql.PutLengthEncodedString([]byte(k)), mysql.PutLengthEncodedString([]byte(v))...)
38+
if !bytes.Contains(data, fixt) {
39+
t.Fatalf("%s attribute not found", k)
40+
}
41+
}
42+
}

client/conn.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package client
22

33
import (
4+
"bytes"
45
"context"
56
"crypto/tls"
67
"fmt"
@@ -28,6 +29,8 @@ type Conn struct {
2829
// client-set capabilities only
2930
ccaps uint32
3031

32+
attributes map[string]string
33+
3134
status uint16
3235

3336
charset string
@@ -221,30 +224,30 @@ func (c *Conn) ExecuteMultiple(query string, perResultCallback ExecPerResultCall
221224
return nil, errors.Trace(err)
222225
}
223226

224-
var buf []byte
225227
var err error
226228
var result *Result
227-
defer utils.ByteSlicePut(buf)
229+
230+
bs := utils.ByteSliceGet(16)
231+
defer utils.ByteSlicePut(bs)
228232

229233
for {
230-
buf, err = c.ReadPacketReuseMem(utils.ByteSliceGet(16)[:0])
234+
bs.B, err = c.ReadPacketReuseMem(bs.B[:0])
231235
if err != nil {
232236
return nil, errors.Trace(err)
233237
}
234238

235-
switch buf[0] {
239+
switch bs.B[0] {
236240
case OK_HEADER:
237-
result, err = c.handleOKPacket(buf)
241+
result, err = c.handleOKPacket(bs.B)
238242
case ERR_HEADER:
239-
err = c.handleErrorPacket(append([]byte{}, buf...))
243+
err = c.handleErrorPacket(bytes.Repeat(bs.B, 1))
240244
result = nil
241245
case LocalInFile_HEADER:
242246
err = ErrMalformPacket
243247
result = nil
244248
default:
245-
result, err = c.readResultset(buf, false)
249+
result, err = c.readResultset(bs.B, false)
246250
}
247-
248251
// call user-defined callback
249252
perResultCallback(result, err)
250253

@@ -302,6 +305,10 @@ func (c *Conn) Rollback() error {
302305
return errors.Trace(err)
303306
}
304307

308+
func (c *Conn) SetAttributes(attributes map[string]string) {
309+
c.attributes = attributes
310+
}
311+
305312
func (c *Conn) SetCharset(charset string) error {
306313
if c.charset == charset {
307314
return nil

client/req.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ func (c *Conn) writeCommandBuf(command byte, arg []byte) error {
2121

2222
length := len(arg) + 1
2323
data := utils.ByteSliceGet(length + 4)
24-
data[4] = command
24+
data.B[4] = command
2525

26-
copy(data[5:], arg)
26+
copy(data.B[5:], arg)
2727

28-
err := c.WritePacket(data)
28+
err := c.WritePacket(data.B)
2929

3030
utils.ByteSlicePut(data)
3131

client/resp.go

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -216,38 +216,42 @@ func (c *Conn) readOK() (*Result, error) {
216216
}
217217

218218
func (c *Conn) readResult(binary bool) (*Result, error) {
219-
firstPkgBuf, err := c.ReadPacketReuseMem(utils.ByteSliceGet(16)[:0])
220-
defer utils.ByteSlicePut(firstPkgBuf)
221-
219+
bs := utils.ByteSliceGet(16)
220+
defer utils.ByteSlicePut(bs)
221+
var err error
222+
bs.B, err = c.ReadPacketReuseMem(bs.B[:0])
222223
if err != nil {
223224
return nil, errors.Trace(err)
224225
}
225226

226-
if firstPkgBuf[0] == OK_HEADER {
227-
return c.handleOKPacket(firstPkgBuf)
228-
} else if firstPkgBuf[0] == ERR_HEADER {
229-
return nil, c.handleErrorPacket(append([]byte{}, firstPkgBuf...))
230-
} else if firstPkgBuf[0] == LocalInFile_HEADER {
227+
switch bs.B[0] {
228+
case OK_HEADER:
229+
return c.handleOKPacket(bs.B)
230+
case ERR_HEADER:
231+
return nil, c.handleErrorPacket(bytes.Repeat(bs.B, 1))
232+
case LocalInFile_HEADER:
231233
return nil, ErrMalformPacket
234+
default:
235+
return c.readResultset(bs.B, binary)
232236
}
233-
234-
return c.readResultset(firstPkgBuf, binary)
235237
}
236238

237239
func (c *Conn) readResultStreaming(binary bool, result *Result, perRowCb SelectPerRowCallback, perResCb SelectPerResultCallback) error {
238-
firstPkgBuf, err := c.ReadPacketReuseMem(utils.ByteSliceGet(16)[:0])
239-
defer utils.ByteSlicePut(firstPkgBuf)
240-
240+
bs := utils.ByteSliceGet(16)
241+
defer utils.ByteSlicePut(bs)
242+
var err error
243+
bs.B, err = c.ReadPacketReuseMem(bs.B[:0])
241244
if err != nil {
242245
return errors.Trace(err)
243246
}
244247

245-
if firstPkgBuf[0] == OK_HEADER {
248+
switch bs.B[0] {
249+
case OK_HEADER:
246250
// https://dev.mysql.com/doc/internals/en/com-query-response.html
247251
// 14.6.4.1 COM_QUERY Response
248252
// If the number of columns in the resultset is 0, this is a OK_Packet.
249253

250-
okResult, err := c.handleOKPacket(firstPkgBuf)
254+
okResult, err := c.handleOKPacket(bs.B)
251255
if err != nil {
252256
return errors.Trace(err)
253257
}
@@ -262,13 +266,13 @@ func (c *Conn) readResultStreaming(binary bool, result *Result, perRowCb SelectP
262266
result.Reset(0)
263267
}
264268
return nil
265-
} else if firstPkgBuf[0] == ERR_HEADER {
266-
return c.handleErrorPacket(append([]byte{}, firstPkgBuf...))
267-
} else if firstPkgBuf[0] == LocalInFile_HEADER {
269+
case ERR_HEADER:
270+
return c.handleErrorPacket(bytes.Repeat(bs.B, 1))
271+
case LocalInFile_HEADER:
268272
return ErrMalformPacket
273+
default:
274+
return c.readResultsetStreaming(bs.B, binary, result, perRowCb, perResCb)
269275
}
270-
271-
return c.readResultsetStreaming(firstPkgBuf, binary, result, perRowCb, perResCb)
272276
}
273277

274278
func (c *Conn) readResultset(data []byte, binary bool) (*Result, error) {

client/tls.go

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,28 @@ func NewClientTLSConfig(caPem, certPem, keyPem []byte, insecureSkipVerify bool,
1313
panic("failed to add ca PEM")
1414
}
1515

16-
cert, err := tls.X509KeyPair(certPem, keyPem)
17-
if err != nil {
18-
panic(err)
19-
}
16+
var config *tls.Config
2017

21-
config := &tls.Config{
22-
Certificates: []tls.Certificate{cert},
23-
RootCAs: pool,
24-
InsecureSkipVerify: insecureSkipVerify,
25-
ServerName: serverName,
18+
// Allow cert and key to be optional
19+
// Send through `make([]byte, 0)` for "nil"
20+
if string(certPem) != "" && string(keyPem) != "" {
21+
cert, err := tls.X509KeyPair(certPem, keyPem)
22+
if err != nil {
23+
panic(err)
24+
}
25+
config = &tls.Config{
26+
RootCAs: pool,
27+
Certificates: []tls.Certificate{cert},
28+
InsecureSkipVerify: insecureSkipVerify,
29+
ServerName: serverName,
30+
}
31+
} else {
32+
config = &tls.Config{
33+
RootCAs: pool,
34+
InsecureSkipVerify: insecureSkipVerify,
35+
ServerName: serverName,
36+
}
2637
}
38+
2739
return config
2840
}

0 commit comments

Comments
 (0)