Skip to content

Commit d4c3311

Browse files
committed
add field list support
1 parent f742316 commit d4c3311

File tree

4 files changed

+104
-5
lines changed

4 files changed

+104
-5
lines changed

client/conn.go

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ type Conn struct {
3535
salt []byte
3636

3737
lastPing int64
38+
39+
pkgErr error
3840
}
3941

4042
func (c *Conn) Connect(addr string, user string, password string, db string) error {
@@ -109,11 +111,15 @@ func (c *Conn) Close() error {
109111
}
110112

111113
func (c *Conn) readPacket() ([]byte, error) {
112-
return c.pkg.ReadPacket()
114+
d, err := c.pkg.ReadPacket()
115+
c.pkgErr = err
116+
return d, err
113117
}
114118

115119
func (c *Conn) writePacket(data []byte) error {
116-
return c.pkg.WritePacket(data)
120+
err := c.pkg.WritePacket(data)
121+
c.pkgErr = err
122+
return err
117123
}
118124

119125
func (c *Conn) readInitialHandshake() error {
@@ -400,6 +406,40 @@ func (c *Conn) SetCharset(charset string) error {
400406
}
401407
}
402408

409+
func (c *Conn) FieldList(table string, wildcard string) ([]*Field, error) {
410+
if err := c.writeCommandStrStr(COM_FIELD_LIST, table, wildcard); err != nil {
411+
return nil, err
412+
}
413+
414+
data, err := c.readPacket()
415+
if err != nil {
416+
return nil, err
417+
}
418+
419+
fs := make([]*Field, 0, 4)
420+
var f *Field
421+
if data[0] == ERR_HEADER {
422+
return nil, c.handleErrorPacket(data)
423+
} else {
424+
for {
425+
if data, err = c.readPacket(); err != nil {
426+
return nil, err
427+
}
428+
429+
// EOF Packet
430+
if c.isEOFPacket(data) {
431+
return fs, nil
432+
}
433+
434+
if f, err = FieldData(data).Parse(); err != nil {
435+
return nil, err
436+
}
437+
fs = append(fs, f)
438+
}
439+
}
440+
return nil, fmt.Errorf("field list error")
441+
}
442+
403443
func (c *Conn) exec(query string) (*Result, error) {
404444
if err := c.writeCommandStr(COM_QUERY, query); err != nil {
405445
return nil, err

client/db.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ func (db *DB) PopConn() (co *Conn, err error) {
132132
func (db *DB) PushConn(co *Conn, err error) {
133133
var closeConn *Conn = nil
134134

135-
if err == ErrBadConn {
135+
if err != nil {
136136
closeConn = co
137137
} else {
138138
if db.idleConns > 0 {
@@ -167,7 +167,7 @@ type SqlConn struct {
167167

168168
func (p *SqlConn) Close() {
169169
if p.Conn != nil {
170-
p.db.PushConn(p.Conn, nil)
170+
p.db.PushConn(p.Conn, p.Conn.pkgErr)
171171
p.Conn = nil
172172
}
173173
}

proxy/conn.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ func (c *Conn) readHandshakeResponse() error {
216216
checkAuth := CalcPassword(c.salt, []byte(c.server.cfg.Password))
217217

218218
if !bytes.Equal(auth, checkAuth) {
219-
return NewDefaultError(ER_ACCESS_DENIED_ERROR, c.c.RemoteAddr().String(), c.user)
219+
return NewDefaultError(ER_ACCESS_DENIED_ERROR, c.c.RemoteAddr().String(), c.user, "Yes")
220220
}
221221

222222
pos += authLen
@@ -265,6 +265,10 @@ func (c *Conn) Run() {
265265
}
266266
}
267267

268+
if c.closed {
269+
return
270+
}
271+
268272
c.pkg.Sequence = 0
269273
}
270274
}
@@ -274,6 +278,9 @@ func (c *Conn) dispatch(data []byte) error {
274278
data = data[1:]
275279

276280
switch cmd {
281+
case COM_QUIT:
282+
c.Close()
283+
return nil
277284
case COM_QUERY:
278285
return c.handleQuery(hack.String(data))
279286
case COM_PING:
@@ -284,6 +291,8 @@ func (c *Conn) dispatch(data []byte) error {
284291
} else {
285292
return c.writeOK(nil)
286293
}
294+
case COM_FIELD_LIST:
295+
return c.handleFieldList(data)
287296
case COM_STMT_PREPARE:
288297
return c.handleStmtPrepare(hack.String(data))
289298
case COM_STMT_EXECUTE:

proxy/conn_select.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package proxy
22

33
import (
4+
"bytes"
45
"fmt"
56
"github.com/siddontang/mixer/hack"
67
. "github.com/siddontang/mixer/mysql"
@@ -176,3 +177,52 @@ func (c *Conn) buildSimpleSelectResult(value interface{}, name []byte, asName []
176177

177178
return c.buildResultset([]*Field{field}, [][]interface{}{[]interface{}{value}})
178179
}
180+
181+
func (c *Conn) handleFieldList(data []byte) error {
182+
index := bytes.IndexByte(data, 0x00)
183+
table := string(data[0:index])
184+
wildcard := string(data[index+1:])
185+
186+
if c.schema == nil {
187+
return NewDefaultError(ER_NO_DB_ERROR)
188+
}
189+
190+
nodeName := c.schema.rule.GetRule(table).Nodes[0]
191+
192+
n := c.server.getNode(nodeName)
193+
194+
co, err := n.getMasterConn()
195+
if err != nil {
196+
return err
197+
}
198+
defer co.Close()
199+
200+
if err = co.UseDB(c.schema.db); err != nil {
201+
return err
202+
}
203+
204+
if fs, err := co.FieldList(table, wildcard); err != nil {
205+
return err
206+
} else {
207+
return c.writeFieldList(c.status, fs)
208+
}
209+
}
210+
211+
func (c *Conn) writeFieldList(status uint16, fs []*Field) error {
212+
c.affectedRows = int64(-1)
213+
214+
data := make([]byte, 4, 1024)
215+
216+
for _, v := range fs {
217+
data = data[0:4]
218+
data = append(data, v.Dump()...)
219+
if err := c.writePacket(data); err != nil {
220+
return err
221+
}
222+
}
223+
224+
if err := c.writeEOF(status); err != nil {
225+
return err
226+
}
227+
return nil
228+
}

0 commit comments

Comments
 (0)