Skip to content

Commit

Permalink
refactor build result set
Browse files Browse the repository at this point in the history
  • Loading branch information
siddontang committed Aug 19, 2014
1 parent d4c3311 commit 928bb5d
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 270 deletions.
39 changes: 0 additions & 39 deletions proxy/conn_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,42 +429,3 @@ func (c *Conn) limitSelectResult(r *Resultset, stmt *sqlparser.Select) error {

return nil
}

func (c *Conn) writeResultset(status uint16, r *Resultset) error {
c.affectedRows = int64(-1)

columnLen := PutLengthEncodedInt(uint64(len(r.Fields)))

data := make([]byte, 4, 1024)

data = append(data, columnLen...)
if err := c.writePacket(data); err != nil {
return err
}

for _, v := range r.Fields {
data = data[0:4]
data = append(data, v.Dump()...)
if err := c.writePacket(data); err != nil {
return err
}
}

if err := c.writeEOF(status); err != nil {
return err
}

for _, v := range r.RowDatas {
data = data[0:4]
data = append(data, v...)
if err := c.writePacket(data); err != nil {
return err
}
}

if err := c.writeEOF(status); err != nil {
return err
}

return nil
}
140 changes: 140 additions & 0 deletions proxy/conn_resultset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package proxy

import (
"fmt"
"github.com/siddontang/mixer/hack"
. "github.com/siddontang/mixer/mysql"
"strconv"
)

func formatValue(value interface{}) ([]byte, error) {
switch v := value.(type) {
case int8:
return strconv.AppendInt(nil, int64(v), 10), nil
case int16:
return strconv.AppendInt(nil, int64(v), 10), nil
case int32:
return strconv.AppendInt(nil, int64(v), 10), nil
case int64:
return strconv.AppendInt(nil, int64(v), 10), nil
case int:
return strconv.AppendInt(nil, int64(v), 10), nil
case uint8:
return strconv.AppendUint(nil, uint64(v), 10), nil
case uint16:
return strconv.AppendUint(nil, uint64(v), 10), nil
case uint32:
return strconv.AppendUint(nil, uint64(v), 10), nil
case uint64:
return strconv.AppendUint(nil, uint64(v), 10), nil
case uint:
return strconv.AppendUint(nil, uint64(v), 10), nil
case float32:
return strconv.AppendFloat(nil, float64(v), 'f', -1, 64), nil
case float64:
return strconv.AppendFloat(nil, float64(v), 'f', -1, 64), nil
case []byte:
return v, nil
case string:
return hack.Slice(v), nil
default:
return nil, fmt.Errorf("invalid type %T", value)
}
}

func formatField(field *Field, value interface{}) error {
switch value.(type) {
case int8, int16, int32, int64, int:
field.Charset = 63
field.Type = MYSQL_TYPE_LONGLONG
field.Flag = BINARY_FLAG | NOT_NULL_FLAG
case uint8, uint16, uint32, uint64, uint:
field.Charset = 63
field.Type = MYSQL_TYPE_LONGLONG
field.Flag = BINARY_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG
case string, []byte:
field.Charset = 33
field.Type = MYSQL_TYPE_VAR_STRING
default:
return fmt.Errorf("unsupport type %T for resultset", value)
}
return nil
}

func (c *Conn) buildResultset(names []string, values [][]interface{}) (*Resultset, error) {
r := new(Resultset)

r.Fields = make([]*Field, len(names))

var row []byte
var b []byte
var err error

for i, vs := range values {
if len(vs) != len(r.Fields) {
return nil, fmt.Errorf("row %d has %d column not equal %d", i, len(vs), len(r.Fields))
}

row = row[0:0]
for j, value := range vs {
if i == 0 {
field := r.Fields[j]
field.Name = hack.Slice(names[j])

if err = formatField(field, value); err != nil {
return nil, err
}
}
b, err = formatValue(value)

if err != nil {
return nil, err
}

row = append(row, PutLengthEncodedString(b)...)
}

r.RowDatas = append(r.RowDatas, row)
}

return r, nil
}

func (c *Conn) writeResultset(status uint16, r *Resultset) error {
c.affectedRows = int64(-1)

columnLen := PutLengthEncodedInt(uint64(len(r.Fields)))

data := make([]byte, 4, 1024)

data = append(data, columnLen...)
if err := c.writePacket(data); err != nil {
return err
}

for _, v := range r.Fields {
data = data[0:4]
data = append(data, v.Dump()...)
if err := c.writePacket(data); err != nil {
return err
}
}

if err := c.writeEOF(status); err != nil {
return err
}

for _, v := range r.RowDatas {
data = data[0:4]
data = append(data, v...)
if err := c.writePacket(data); err != nil {
return err
}
}

if err := c.writeEOF(status); err != nil {
return err
}

return nil
}
Loading

0 comments on commit 928bb5d

Please sign in to comment.