Skip to content

Commit 9a6056d

Browse files
author
Philio
committed
moved packet result handling to separate file, added most statement functions
1 parent 18e4249 commit 9a6056d

File tree

6 files changed

+164
-290
lines changed

6 files changed

+164
-290
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ GOFILES=mysql.go\
99
writer.go\
1010
packet.go\
1111
convert.go\
12+
handler.go\
1213
result.go\
1314
statement.go
1415

convert.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package mysql
77

88
import "math"
9+
import "os"
910
import "strconv"
1011

1112
// bytes to int
@@ -164,3 +165,54 @@ func btof64(b []byte) float64 {
164165
func f64tob(f float64) []byte {
165166
return ui64tob(math.Float64bits(f))
166167
}
168+
169+
// bytes to length
170+
func btolcb(b []byte) (num uint64, n int, err os.Error) {
171+
switch {
172+
// 0-250 = value of first byte
173+
case b[0] <= 250:
174+
num = uint64(b[0])
175+
n = 1
176+
return
177+
// 251 column value = NULL
178+
case b[0] == 251:
179+
num = 0
180+
n = 1
181+
return
182+
// 252 following 2 = value of following 16-bit word
183+
case b[0] == 252:
184+
n = 3
185+
// 253 following 3 = value of following 24-bit word
186+
case b[0] == 253:
187+
n = 4
188+
// 254 following 8 = value of following 64-bit word
189+
case b[0] == 254:
190+
n = 9
191+
}
192+
// Check there are enough bytes
193+
if len(b) < n {
194+
err = os.EOF
195+
return
196+
}
197+
// Get uint64
198+
t := make([]byte, 8)
199+
copy(t, b[1:n])
200+
num = btoui64(t)
201+
return
202+
}
203+
204+
// length to bytes
205+
func lcbtob(n uint64) (b []byte) {
206+
switch {
207+
// <= 250 = 1 byte
208+
case n <= 250:
209+
b = []byte{byte(n)}
210+
// <= 0xffff = 252 + 2 bytes
211+
case n <= 0xffff:
212+
b = []byte{0xfc, byte(n), byte(n >> 8)}
213+
// <= 0xffffff = 253 + 3 bytes
214+
case n <= 0xffffff:
215+
b = []byte{0xfd, byte(n), byte(n >> 8), byte(n >> 16)}
216+
}
217+
return
218+
}

mysql.go

Lines changed: 7 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,6 @@ func (c *Client) getFields() (err os.Error) {
765765
return
766766
}
767767
if eof {
768-
c.result.fieldPos = 0
769768
break
770769
}
771770
}
@@ -812,18 +811,19 @@ func (c *Client) getResult(types packetType) (eof bool, err os.Error) {
812811
default:
813812
err = &ClientError{CR_UNKNOWN_ERROR, CR_UNKNOWN_ERROR_STR}
814813
case *packetOK:
815-
err = c.processOKResult(p.(*packetOK))
814+
err = handleOK(p.(*packetOK), c, &c.AffectedRows, &c.LastInsertId, &c.Warnings)
816815
case *packetError:
817-
err = c.processErrorResult(p.(*packetError))
816+
err = handleError(p.(*packetError), c)
818817
case *packetEOF:
819818
eof = true
820-
err = c.processEOF(p.(*packetEOF))
819+
err = handleEOF(p.(*packetEOF), c)
821820
case *packetResultSet:
822-
err = c.processResultSetResult(p.(*packetResultSet))
821+
c.result = &Result{c: c}
822+
err = handleResultSet(p.(*packetResultSet), c, c.result)
823823
case *packetField:
824-
err = c.processFieldResult(p.(*packetField))
824+
err = handleField(p.(*packetField), c, c.result)
825825
case *packetRowData:
826-
err = c.processRowResult(p.(*packetRowData))
826+
err = handleRow(p.(*packetRowData), c, c.result)
827827
}
828828
return
829829
}
@@ -836,136 +836,3 @@ func (c *Client) checkSequence(sequence uint8) (err os.Error) {
836836
}
837837
return
838838
}
839-
840-
// Process OK packet
841-
func (c *Client) processOKResult(p *packetOK) (err os.Error) {
842-
// Log OK result
843-
c.log(1, "[%d] Received OK packet", p.sequence)
844-
// Check sequence
845-
err = c.checkSequence(p.sequence)
846-
if err != nil {
847-
return
848-
}
849-
// Store packet data
850-
c.AffectedRows = p.affectedRows
851-
c.LastInsertId = p.insertId
852-
c.Warnings = p.warningCount
853-
c.serverStatus = ServerStatus(p.serverStatus)
854-
// Full logging [level 3]
855-
if c.LogLevel > 2 {
856-
c.logStatus()
857-
}
858-
return
859-
}
860-
861-
// Process error packet
862-
func (c *Client) processErrorResult(p *packetError) (err os.Error) {
863-
// Log error result
864-
c.log(1, "[%d] Received error packet", p.sequence)
865-
// Check sequence
866-
err = c.checkSequence(p.sequence)
867-
if err != nil {
868-
return
869-
}
870-
// Check and unset more results flag
871-
// @todo maybe serverStatus should just be zeroed?
872-
if c.MoreResults() {
873-
c.serverStatus ^= SERVER_MORE_RESULTS_EXISTS
874-
}
875-
// Return error
876-
return &ServerError{Errno(p.errno), Error(p.error)}
877-
}
878-
879-
// Process EOF packet
880-
func (c *Client) processEOF(p *packetEOF) (err os.Error) {
881-
// Log EOF result
882-
c.log(1, "[%d] Received EOF packet", p.sequence)
883-
// Check sequence
884-
err = c.checkSequence(p.sequence)
885-
if err != nil {
886-
return
887-
}
888-
// Store packet data
889-
if p.useStatus {
890-
c.serverStatus = ServerStatus(p.serverStatus)
891-
// Full logging [level 3]
892-
if c.LogLevel > 2 {
893-
c.logStatus()
894-
}
895-
}
896-
return
897-
}
898-
899-
// Process result set packet
900-
func (c *Client) processResultSetResult(p *packetResultSet) (err os.Error) {
901-
// Log error result
902-
c.log(1, "[%d] Received result set packet", p.sequence)
903-
// Check sequence
904-
err = c.checkSequence(p.sequence)
905-
if err != nil {
906-
return
907-
}
908-
// Create new result
909-
c.result = &Result{
910-
c: c,
911-
fieldCount: p.fieldCount,
912-
}
913-
return
914-
}
915-
916-
// Process field packet
917-
func (c *Client) processFieldResult(p *packetField) (err os.Error) {
918-
// Log field result
919-
c.log(1, "[%d] Received field packet", p.sequence)
920-
// Check sequence
921-
err = c.checkSequence(p.sequence)
922-
if err != nil {
923-
return
924-
}
925-
// Check if there is a result set
926-
if c.result == nil || c.result.mode == RESULT_FREE {
927-
return
928-
}
929-
// Assign fields if needed
930-
if len(c.result.fields) == 0 {
931-
c.result.fields = make([]*Field, c.result.fieldCount)
932-
}
933-
// Create new field and add to result
934-
c.result.fields[c.result.fieldPos] = &Field{
935-
Database: p.database,
936-
Table: p.table,
937-
Name: p.name,
938-
Length: p.length,
939-
Type: p.fieldType,
940-
Flags: p.flags,
941-
Decimals: p.decimals,
942-
}
943-
c.result.fieldPos++
944-
return
945-
}
946-
947-
// Process row packet
948-
func (c *Client) processRowResult(p *packetRowData) (err os.Error) {
949-
// Log field result
950-
c.log(1, "[%d] Received row packet", p.sequence)
951-
// Check sequence
952-
err = c.checkSequence(p.sequence)
953-
if err != nil {
954-
return
955-
}
956-
// Check if there is a result set
957-
if c.result == nil || c.result.mode == RESULT_FREE {
958-
return
959-
}
960-
// Stored result
961-
if c.result.mode == RESULT_STORED {
962-
// Cast and append the row
963-
c.result.rows = append(c.result.rows, Row(p.row))
964-
}
965-
// Used result
966-
if c.result.mode == RESULT_USED {
967-
// Only save 1 row, overwrite previous
968-
c.result.rows = []Row{Row(p.row)}
969-
}
970-
return
971-
}

packet.go

Lines changed: 12 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package mysql
88
import (
99
"bytes"
1010
"os"
11+
"fmt"
1112
)
1213

1314
// Packet type identifier
@@ -65,41 +66,6 @@ func (p *packetBase) readSlice(data []byte, delim byte) (slice []byte, err os.Er
6566
return
6667
}
6768

68-
// Read length coded binary
69-
func (p *packetBase) readLengthCodedBinary(data []byte) (num uint64, n int, err os.Error) {
70-
switch {
71-
// 0-250 = value of first byte
72-
case data[0] <= 250:
73-
num = uint64(data[0])
74-
n = 1
75-
return
76-
// 251 column value = NULL
77-
case data[0] == 251:
78-
num = 0
79-
n = 1
80-
return
81-
// 252 following 2 = value of following 16-bit word
82-
case data[0] == 252:
83-
n = 3
84-
// 253 following 3 = value of following 24-bit word
85-
case data[0] == 253:
86-
n = 4
87-
// 254 following 8 = value of following 64-bit word
88-
case data[0] == 254:
89-
n = 9
90-
}
91-
// Check there are enough bytes
92-
if len(data) < n {
93-
err = os.EOF
94-
return
95-
}
96-
// Get uint64
97-
b := make([]byte, 8)
98-
copy(b, data[1:n])
99-
num = btoui64(b)
100-
return
101-
}
102-
10369
// Read length coded string
10470
func (p *packetBase) readLengthCodedString(data []byte) (s string, n int, err os.Error) {
10571
// Read bytes and convert to string
@@ -113,7 +79,7 @@ func (p *packetBase) readLengthCodedString(data []byte) (s string, n int, err os
11379

11480
func (p *packetBase) readLengthCodedBytes(data []byte) (b []byte, n int, err os.Error) {
11581
// Get string length
116-
num, n, err := p.readLengthCodedBinary(data)
82+
num, n, err := btolcb(data)
11783
if err != nil {
11884
return
11985
}
@@ -283,14 +249,14 @@ func (p *packetOK) read(data []byte) (err os.Error) {
283249
// Position (skip first byte/field count)
284250
pos := 1
285251
// Affected rows [length coded binary]
286-
num, n, err := p.readLengthCodedBinary(data[pos:])
252+
num, n, err := btolcb(data[pos:])
287253
if err != nil {
288254
return
289255
}
290256
p.affectedRows = num
291257
pos += n
292258
// Insert id [length coded binary]
293-
num, n, err = p.readLengthCodedBinary(data[pos:])
259+
num, n, err = btolcb(data[pos:])
294260
if err != nil {
295261
return
296262
}
@@ -495,14 +461,14 @@ func (p *packetResultSet) read(data []byte) (err os.Error) {
495461
// Position and bytes read
496462
var pos, n int
497463
// Field count [length coded binary]
498-
p.fieldCount, n, err = p.readLengthCodedBinary(data[pos:])
464+
p.fieldCount, n, err = btolcb(data[pos:])
499465
if err != nil {
500466
return
501467
}
502468
pos += n
503469
// Extra [length coded binary]
504470
if pos < len(data) {
505-
p.extra, n, err = p.readLengthCodedBinary(data[pos:])
471+
p.extra, n, err = btolcb(data[pos:])
506472
if err != nil {
507473
return
508474
}
@@ -594,7 +560,7 @@ func (p *packetField) read(data []byte) (err os.Error) {
594560
pos++
595561
// Default value [len coded binary]
596562
if pos < len(data) {
597-
p.defaultVal, _, err = p.readLengthCodedBinary(data[pos:])
563+
p.defaultVal, _, err = btolcb(data[pos:])
598564
}
599565
} else {
600566
// Table [len coded string]
@@ -651,11 +617,7 @@ func (p *packetRowData) read(data []byte) (err os.Error) {
651617
return
652618
}
653619
// Add to slice
654-
if len(p.row) == 0 {
655-
p.row = []interface{}{b}
656-
} else {
657-
p.row = append(p.row, b)
658-
}
620+
p.row = append(p.row, b)
659621
// Increment position and check for end of packet
660622
pos += n
661623
if pos == len(data) {
@@ -798,13 +760,14 @@ func (p *packetExecute) write() (data []byte, err os.Error) {
798760
}
799761
// Add the packet header
800762
data = p.addHeader(data)
763+
fmt.Printf("%#v\n", data)
801764
return
802765
}
803766

804767
// Binary row struct
805768
type packetRowBinary struct {
806769
packetBase
807-
row []interface{}
770+
data []byte
808771
}
809772

810773
// Row binary packet reader
@@ -815,5 +778,7 @@ func (p *packetRowBinary) read(data []byte) (err os.Error) {
815778
err = &ClientError{CR_MALFORMED_PACKET, CR_MALFORMED_PACKET_STR}
816779
}
817780
}()
781+
// Simply store the row
782+
p.data = data
818783
return
819784
}

result.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ type Field struct {
3232
Table string
3333
Name string
3434
Length uint32
35-
Type uint8
36-
Flags uint16
35+
Type FieldType
36+
Flags FieldFlag
3737
Decimals uint8
3838
}
3939

0 commit comments

Comments
 (0)