Skip to content

Commit ccad956

Browse files
committed
new i/o buffer
1 parent 13d9765 commit ccad956

File tree

4 files changed

+89
-18
lines changed

4 files changed

+89
-18
lines changed

buffer.go

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
2+
//
3+
// Copyright 2013 Julien Schmidt. All rights reserved.
4+
// http://www.julienschmidt.com
5+
//
6+
// This Source Code Form is subject to the terms of the Mozilla Public
7+
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
8+
// You can obtain one at http://mozilla.org/MPL/2.0/.
9+
10+
package mysql
11+
12+
import (
13+
"io"
14+
)
15+
16+
const (
17+
defaultBufSize = 4096
18+
)
19+
20+
type buffer struct {
21+
buf []byte
22+
rd io.Reader
23+
idx int
24+
length int
25+
}
26+
27+
func newBuffer(rd io.Reader) *buffer {
28+
return &buffer{
29+
buf: make([]byte, defaultBufSize),
30+
rd: rd,
31+
}
32+
}
33+
34+
// fill reads at least _need_ bytes in the buffer
35+
// existing data in the buffer gets lost
36+
func (b *buffer) fill(need int) (err error) {
37+
b.idx = 0
38+
b.length = 0
39+
40+
n := 0
41+
for err == nil && b.length < need {
42+
n, err = b.rd.Read(b.buf[b.length:])
43+
b.length += n
44+
}
45+
46+
return
47+
}
48+
49+
// read len(p) bytes
50+
func (b *buffer) read(p []byte) (err error) {
51+
need := len(p)
52+
53+
if b.length < need {
54+
if b.length > 0 {
55+
copy(p[0:b.length], b.buf[b.idx:])
56+
need -= b.length
57+
p = p[b.length:]
58+
59+
b.idx = 0
60+
b.length = 0
61+
}
62+
63+
if need >= len(b.buf) {
64+
var n int
65+
has := 0
66+
for err == nil && need > has {
67+
n, err = b.rd.Read(p[has:])
68+
has += n
69+
}
70+
return
71+
}
72+
73+
err = b.fill(need) // err deferred
74+
}
75+
76+
copy(p, b.buf[b.idx:])
77+
b.idx += need
78+
b.length -= need
79+
return
80+
}

connection.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
package mysql
1111

1212
import (
13-
"bufio"
1413
"database/sql/driver"
1514
"errors"
1615
"net"
@@ -21,7 +20,7 @@ type mysqlConn struct {
2120
cfg *config
2221
server *serverSettings
2322
netConn net.Conn
24-
bufReader *bufio.Reader
23+
buf *buffer
2524
protocol uint8
2625
sequence uint8
2726
affectedRows uint64
@@ -96,7 +95,7 @@ func (mc *mysqlConn) Begin() (driver.Tx, error) {
9695
func (mc *mysqlConn) Close() (err error) {
9796
mc.writeCommandPacket(COM_QUIT)
9897
mc.cfg = nil
99-
mc.bufReader = nil
98+
mc.buf = nil
10099
mc.netConn.Close()
101100
mc.netConn = nil
102101
return

driver.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
package mysql
1010

1111
import (
12-
"bufio"
1312
"database/sql"
1413
"database/sql/driver"
1514
"net"
@@ -32,7 +31,7 @@ func (d *mysqlDriver) Open(dsn string) (driver.Conn, error) {
3231
if err != nil {
3332
return nil, err
3433
}
35-
mc.bufReader = bufio.NewReader(mc.netConn)
34+
mc.buf = newBuffer(mc.netConn)
3635

3736
// Reading Handshake Initialization Packet
3837
err = mc.readInitPacket()

packets.go

+6-13
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ import (
2626
func (mc *mysqlConn) readPacket() (data []byte, err error) {
2727
// Read header
2828
data = make([]byte, 4)
29-
var n, add int
30-
for err == nil && n < 4 {
31-
add, err = mc.bufReader.Read(data[n:])
32-
n += add
29+
err = mc.buf.read(data)
30+
if err != nil {
31+
errLog.Print(err)
32+
return nil, driver.ErrBadConn
3333
}
3434

3535
// Packet Length
@@ -55,15 +55,8 @@ func (mc *mysqlConn) readPacket() (data []byte, err error) {
5555

5656
// Read rest of packet
5757
data = make([]byte, pktLen)
58-
n = 0
59-
for err == nil && n < int(pktLen) {
60-
add, err = mc.bufReader.Read(data[n:])
61-
n += add
62-
}
63-
if err != nil || n < int(pktLen) {
64-
if err == nil {
65-
err = fmt.Errorf("Length of read data (%d) does not match body length (%d)", n, pktLen)
66-
}
58+
err = mc.buf.read(data)
59+
if err != nil {
6760
errLog.Print(err)
6861
return nil, driver.ErrBadConn
6962
}

0 commit comments

Comments
 (0)