package xugu import ( "database/sql/driver" "encoding/binary" "errors" "fmt" "strconv" "strings" "time" ) type xuguValue struct { // 布尔值,如果值为 true,表示当前字段的数据类型是大对象数据类型 islob bool //字段名 paramName []byte //paramNameLength [2]byte // 字段的实际值 value []byte // 值的长度 valueLength int // 字段的类型 types fieldType } // 判断参数个数 func assertParamCount(query string) int { fmt.Println("----assertParamCount func 判断参数个数") paramCount := strings.Count(query, "?") fmt.Println("Parse.param_count = ", paramCount) return paramCount } func assertParamType(dV driver.Value, values *[]xuguValue) error { var dest xuguValue switch srcv := dV.(type) { case int64: S := strconv.FormatInt(srcv, 10) dest.value = []byte(S) dest.valueLength = strings.Count(S, "") - 1 dest.islob = false dest.types = fieldType_I8 case float32: S := strconv.FormatFloat(float64(srcv), 'f', 6, 64) dest.value = []byte(S) dest.valueLength = strings.Count(S, "") - 1 dest.islob = false dest.types = fieldType_R4 case float64: S := strconv.FormatFloat(srcv, 'f', 15, 64) dest.value = []byte(S) dest.valueLength = strings.Count(S, "") - 1 dest.islob = false dest.types = fieldType_R8 case bool: S := strconv.FormatBool(srcv) dest.value = []byte(S) dest.valueLength = strings.Count(S, "") - 1 dest.islob = false dest.types = fieldType_BOOL case string: dest.value = []byte(srcv) dest.valueLength = strings.Count(srcv, "") - 1 dest.islob = false dest.types = fieldType_CHAR case time.Time: tm := fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", srcv.Year(), int(srcv.Month()), srcv.Day(), srcv.Hour(), srcv.Minute(), srcv.Second()) dest.value = []byte(tm) dest.valueLength = strings.Count(tm, "") - 1 dest.islob = false dest.types = fieldType_TIME case []byte: dest.value = srcv dest.valueLength = len(srcv) dest.islob = true dest.types = fieldType_BLOB case nil: dest.value = []byte("xugusql") dest.valueLength = 0 dest.islob = false dest.types = fieldType_CHAR default: return errors.New("unknown data type") } *values = append(*values, dest) return nil } func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) { var err error aR := allResult{} for { char := readBuf.peekChar() fmt.Println("parseMsg 内的 peekChar: ", char, "-", string(char)) switch char { case 'K': fmt.Println("消息类型为K") readBuf.reset() return &aR, nil case '$': readBuf.idx++ fmt.Println("消息类型为$") if aR.f, err = parseFormArgDescri(readBuf); err != nil { return nil, err } aR.rt = formArgDescri return &aR, err case 'A': readBuf.idx++ fmt.Println("消息类型为A") if aR.s, err = parseSelectResult(readBuf); err != nil { return nil, err } aR.rt = selectResult return &aR, err case 'I': readBuf.idx++ fmt.Println("消息类型为I") if aR.i, err = parseInsertResult(readBuf); err != nil { return nil, err } aR.rt = insertResult return &aR, err case 'U': fmt.Println("消息类型为U") readBuf.idx++ if aR.u, err = parseUpdateResult(readBuf); err != nil { return nil, err } aR.rt = updateResult return &aR, err case 'D': fmt.Println("消息类型为D") readBuf.idx++ readBuf.idx++ if aR.d, err = parseDeleteResult(readBuf); err != nil { return nil, err } aR.rt = deleteResult return &aR, err case 'E': fmt.Println("消息类型为E") readBuf.idx++ if aR.e, err = parseErrInfo(readBuf); err != nil { return nil, err } pConn.errStr = aR.e.ErrStr aR.rt = errInfo return &aR, err case 'W': fmt.Println("消息类型为W") readBuf.idx++ if aR.w, err = parseWarnInfo(readBuf); err != nil { return nil, err } aR.rt = warnInfo return &aR, err case 'M': fmt.Println("消息类型为M") readBuf.idx++ if aR.m, err = parseMessage(readBuf); err != nil { return nil, err } aR.rt = message return &aR, err default: fmt.Println("消息类型为其他") return nil, errors.New("parseMsg: unknown message type") } } } func parseSelectResult(readBuf *buffer) (*SelectResult, error) { fmt.Println("调用 parseSelectResult") data := &SelectResult{} char := readBuf.peekChar() fmt.Println("--=char: ", string(char), char) //Field_Num Field_Num := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) data.Field_Num = Field_Num data.rowIdx = 0 fmt.Println("Field_Num: ", data.Field_Num) //获取字段信息 for i := 0; i < int(Field_Num); i++ { field := FieldDescri{} //Field_Name_Len field.FieldNameLen = int(binary.LittleEndian.Uint32(readBuf.readNext(4, true))) fmt.Println("field.FieldNameLen: ", field.FieldNameLen) //Field_Name: field.FieldName = string(readBuf.readNext(field.FieldNameLen, false)) fmt.Println("field.Field_Name: ", field.FieldName) //Field_DType: field.FieldType = fieldType(binary.LittleEndian.Uint32(readBuf.readNext(4, true))) fmt.Println("field.FieldType: ", field.FieldType) //Field_Preci_Scale: fieldPreciScale := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) if int32(fieldPreciScale) <= 0 { field.FieldPreciScale = fieldPreciScaleInfo{ scale: 0, accuracy: 0, } } else { field.FieldPreciScale = fieldPreciScaleInfo{ scale: uint16(fieldPreciScale >> 16), accuracy: uint16(fieldPreciScale & 0xFFFF), } } fmt.Println("field.FieldPreciScale: ", field.FieldPreciScale) //Field_Flag: field.FieldFlag = binary.LittleEndian.Uint32(readBuf.readNext(4, true)) fmt.Println("field.FieldFlag: ", field.FieldFlag) data.Fields = append(data.Fields, field) } data.Values = make([][]FieldValue, data.Field_Num) //获取字段的行值,并判断类型 // 使用 Peek 方法检查下一个字节是否为'R'或'K' fmt.Println("\n\n=========开始获取行数据=================================") defer func() { fmt.Println("\n\n=========获取行数据结束=================================") }() char = readBuf.peekChar() fmt.Println(" --char: ", string(char)) readBuf.idx++ if char == 'K' { return data, nil } else if char == 'R' { colIdx := 0 //typeIdx := 0 fmt.Println("开始循环 ") for { col := FieldValue{} //获取数据的大小 col.Col_len = binary.LittleEndian.Uint32(readBuf.readNext(4, true)) fmt.Println("数据大小为: ", col.Col_len) col.Col_Data = readBuf.readNext(int(col.Col_len), false) fmt.Println("fieldTypeVarChar data: ", col.Col_Data, string(col.Col_Data)) data.Values[colIdx] = append(data.Values[colIdx], col) colIdx++ fmt.Println("从查询返回 解析出的值 :", col.Col_Data, string(col.Col_Data)) char := readBuf.peekChar() //既不是R 也不是K 代表该行还有其他字段内容没有读取完成 if char == 'R' { readBuf.idx++ colIdx = 0 continue } else if char == 'K' { return data, nil //break } } //for end } else if char == '$' { fmt.Println(" 查询返回 $ ") fad, err := parseFormArgDescri(readBuf) if err != nil { return nil, err } char := readBuf.peekChar() //既不是R 也不是K 代表该行还有其他字段内容没有读取完成 if char == 'K' { data.fad = fad return data, nil //break } return nil, errors.New("select to $ 解析失败") } else { return nil, errors.New("解析失败") } } // func parseSelectResult2(readBuf *buffer) (*SelectResult, error) { // data := &SelectResult{} // char := readBuf.peekChar() // if char == 'K' { // return nil, errors.New("parseSelectResult error char is K") // } // fmt.Println("--=char: ", string(char)) // //Field_Num // Field_Num := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) // data.Field_Num = Field_Num // //data.rowIdx = 0 // fmt.Println("Field_Num: ", data.Field_Num) // //获取字段信息 // for i := 0; i < int(Field_Num); i++ { // field := FieldDescri{} // //Field_Name_Len // field.FieldNameLen = int(binary.LittleEndian.Uint32(readBuf.readNext(4, true))) // fmt.Println("field.FieldNameLen: ", field.FieldNameLen) // //Field_Name: // field.FieldName = string(readBuf.readNext(field.FieldNameLen, false)) // fmt.Println("field.Field_Name: ", field.FieldName) // //Field_DType: // field.FieldType = fieldType(binary.LittleEndian.Uint32(readBuf.readNext(4, true))) // fmt.Println("field.FieldType: ", field.FieldType) // //Field_Preci_Scale: // fieldPreciScale := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) // if int32(fieldPreciScale) <= 0 { // field.FieldPreciScale = fieldPreciScaleInfo{ // scale: 0, // accuracy: 0, // } // } else { // field.FieldPreciScale = fieldPreciScaleInfo{ // scale: uint16(fieldPreciScale >> 16), // accuracy: uint16(fieldPreciScale & 0xFFFF), // } // } // fmt.Println("field.FieldPreciScale: ", field.FieldPreciScale) // //Field_Flag: // field.FieldFlag = binary.LittleEndian.Uint32(readBuf.readNext(4, true)) // fmt.Println("field.FieldFlag: ", field.FieldFlag) // data.Fields = append(data.Fields, field) // } // //获取字段的行值,并判断类型 // // 使用 Peek 方法检查下一个字节是否为'R'或'K' // fmt.Println("\n\n=========开始获取行数据=================================") // defer func() { // fmt.Println("\n\n=========获取行数据结束=================================") // }() // //data.Values = make([][]FieldValue, 0) // data.Values = [][]FieldValue // colIdx := 0 // char = readBuf.peekChar() // fmt.Println(" --char: ", string(char)) // readBuf.idx++ // if char == 'K' { // return data, nil // } else if char == 'R' { // for { // col := FieldValue{} // //获取数据的大小 // col.Col_len = binary.LittleEndian.Uint32(readBuf.readNext(4, true)) // fmt.Println("数据大小为: ", col.Col_len) // col.Col_Data = readBuf.readNext(int(col.Col_len), false) // fmt.Println("fieldTypeVarChar data: ", col.Col_Data, string(col.Col_Data)) // data.Values[colIdx] = append(data.Values[colIdx], col) // colIdx++ // fmt.Println("从查询返回 解析出的值 :", col.Col_Data, string(col.Col_Data)) // char := readBuf.peekChar() // //next for // if char == 'R' { // readBuf.idx++ // continue // //end parse // } else if char == 'K' { // return data, nil // } // //swich end // fmt.Println("循环结束") // fmt.Printf("解析请求 data:%#v\n", data.Fields) // return data, nil // } //for end // } else { // return data, errors.New("select parse error") // } // } func parseInsertResult(readBuf *buffer) (*InsertResult, error) { //Rowid_Len Rowid_Len := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) //Rowid_Data encoded := readBuf.readNext(int(Rowid_Len), false) //检测是否结束 char := readBuf.peekChar() if char == 'K' { return &InsertResult{ RowidLen: Rowid_Len, RowidData: encoded, }, nil } return nil, errors.New("parseInsertResult error") } func parseUpdateResult(readBuf *buffer) (*UpdateResult, error) { updateNum := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) return &UpdateResult{UpdateNum: updateNum}, nil } func parseDeleteResult(readBuf *buffer) (*DeleteResult, error) { deleteNum := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) return &DeleteResult{DeleteNum: deleteNum}, nil } func parseProcRet(readBuf *buffer) (*ProcRet, error) { retDType := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) retDataLen := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) retData := readBuf.readNext(int(retDataLen), false) return &ProcRet{RetDType: retDType, RetDataLen: retDataLen, RetData: retData}, nil } func parseOutParamRet(readBuf *buffer) (*OutParamRet, error) { outParamNo := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) outParamDType := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) outParamLen := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) outParamData := readBuf.readNext(int(outParamLen), false) return &OutParamRet{ OutParamNo: outParamNo, OutParamDType: outParamDType, OutParamLen: outParamLen, OutParamData: outParamData, }, nil } func parseErrInfo(readBuf *buffer) (*ErrInfo, error) { errStrLen := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) errStr := readBuf.readNext(int(errStrLen), false) return &ErrInfo{ErrStrLen: errStrLen, ErrStr: errStr}, nil } func parseWarnInfo(readBuf *buffer) (*WarnInfo, error) { warnStrLen := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) warnStr := readBuf.readNext(int(warnStrLen), false) return &WarnInfo{WarnStrLen: warnStrLen, WarnStr: warnStr}, nil } func parseMessage(readBuf *buffer) (*Message, error) { msgStrLen := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) msgStr := readBuf.readNext(int(msgStrLen), false) return &Message{MsgStrLen: msgStrLen, MsgStr: msgStr}, nil } func parseFormArgDescri(readBuf *buffer) (*FormArgDescri, error) { // FormArgDescri: '$' Arg_Num { Arg_Name_Len Arg_Name Arg_No Arg_DType Arg_Preci_Scale }+ Arg_Num := binary.LittleEndian.Uint32(readBuf.readNext(4, true)) formArgDescri := &FormArgDescri{ArgNum: Arg_Num} fmt.Println("-- parseFormArgDescri Arg_Num:", Arg_Num) for i := 0; i < int(Arg_Num); i++ { arg := ArgDescri{} //Arg_Name_Len arg.ArgNameLen = binary.LittleEndian.Uint32(readBuf.readNext(4, true)) //Arg_Name arg.ArgName = readBuf.readNext(int(arg.ArgNameLen), false) //Arg_No arg.ArgNo = binary.LittleEndian.Uint32(readBuf.readNext(4, true)) //Argg_DType arg.ArgDType = binary.LittleEndian.Uint32(readBuf.readNext(4, true)) //Arg_Preci_Scale arg.ArgPreciScale = binary.LittleEndian.Uint32(readBuf.readNext(4, true)) formArgDescri.Args = append(formArgDescri.Args, arg) } fmt.Printf("formArgDescri %#v \n", formArgDescri) return formArgDescri, nil }