func (p RowData) ParseText(f []*Field) ([]interface{}, error) { data := make([]interface{}, len(f)) var err error var v []byte var isNull, isUnsigned bool var pos int = 0 var n int = 0 for i := range f { v, isNull, n, err = utils.LengthEnodedString(p[pos:]) if err != nil { return nil, err } pos += n if isNull { data[i] = nil } else { isUnsigned = (f[i].Flag&UNSIGNED_FLAG > 0) switch f[i].Type { case MYSQL_TYPE_TINY, MYSQL_TYPE_SHORT, MYSQL_TYPE_INT24, MYSQL_TYPE_LONGLONG, MYSQL_TYPE_YEAR: if isUnsigned { data[i], err = strconv.ParseUint(string(v), 10, 64) } else { data[i], err = strconv.ParseInt(string(v), 10, 64) } case MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE: data[i], err = strconv.ParseFloat(string(v), 64) default: data[i] = v } if err != nil { return nil, err } } } return data, nil }
func (p RowData) ParseBinary(f []*Field) ([]interface{}, error) { data := make([]interface{}, len(f)) if p[0] != OK_HEADER { return nil, ErrMalformPacket } pos := 1 + ((len(f) + 7 + 2) >> 3) nullBitmap := p[1:pos] var isUnsigned bool var isNull bool var n int var err error var v []byte for i := range data { if nullBitmap[(i+2)/8]&(1<<(uint(i+2)%8)) > 0 { data[i] = nil continue } isUnsigned = f[i].Flag&UNSIGNED_FLAG > 0 switch f[i].Type { case MYSQL_TYPE_NULL: data[i] = nil continue case MYSQL_TYPE_TINY: if isUnsigned { data[i] = uint64(p[pos]) } else { data[i] = int64(p[pos]) } pos++ continue case MYSQL_TYPE_SHORT, MYSQL_TYPE_YEAR: if isUnsigned { data[i] = uint64(binary.LittleEndian.Uint16(p[pos : pos+2])) } else { data[i] = int64((binary.LittleEndian.Uint16(p[pos : pos+2]))) } pos += 2 continue case MYSQL_TYPE_INT24, MYSQL_TYPE_LONG: if isUnsigned { data[i] = uint64(binary.LittleEndian.Uint32(p[pos : pos+4])) } else { data[i] = int64(binary.LittleEndian.Uint32(p[pos : pos+4])) } pos += 4 continue case MYSQL_TYPE_LONGLONG: if isUnsigned { data[i] = binary.LittleEndian.Uint64(p[pos : pos+8]) } else { data[i] = int64(binary.LittleEndian.Uint64(p[pos : pos+8])) } pos += 8 continue case MYSQL_TYPE_FLOAT: data[i] = float64(math.Float32frombits(binary.LittleEndian.Uint32(p[pos : pos+4]))) pos += 4 continue case MYSQL_TYPE_DOUBLE: data[i] = math.Float64frombits(binary.LittleEndian.Uint64(p[pos : pos+8])) pos += 8 continue case MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, MYSQL_TYPE_BIT, MYSQL_TYPE_ENUM, MYSQL_TYPE_SET, MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB, MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_STRING, MYSQL_TYPE_GEOMETRY: v, isNull, n, err = utils.LengthEnodedString(p[pos:]) pos += n if err != nil { return nil, err } if !isNull { data[i] = v continue } else { data[i] = nil continue } case MYSQL_TYPE_DATE, MYSQL_TYPE_NEWDATE: var num uint64 num, isNull, n = LengthEncodedInt(p[pos:]) pos += n if isNull { data[i] = nil continue } data[i], err = utils.FormatBinaryDate(int(num), p[pos:]) pos += int(num) if err != nil { return nil, err } case MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_DATETIME: var num uint64 num, isNull, n = utils.LengthEncodedInt(p[pos:]) pos += n if isNull { data[i] = nil continue } data[i], err = utils.FormatBinaryDateTime(int(num), p[pos:]) pos += int(num) if err != nil { return nil, err } case MYSQL_TYPE_TIME: var num uint64 num, isNull, n = utils.LengthEncodedInt(p[pos:]) pos += n if isNull { data[i] = nil continue } data[i], err = utils.FormatBinaryTime(int(num), p[pos:]) pos += int(num) if err != nil { return nil, err } default: return nil, fmt.Errorf("Stmt Unknown FieldType %d %s", f[i].Type, f[i].Name) } } return data, nil }