xugusql_sock_recv.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. package xugu
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "errors"
  6. )
  7. const RETURN_PREPARE_SELECT = 19665
  8. func rhRecvStr(pConn *xugusqlConn, valp *[]byte) (int, error) {
  9. var len uint32
  10. if err := rhRecvInt32(pConn, &len); err != nil {
  11. return -4, err
  12. }
  13. pBuff := make([]byte, len+1)
  14. if err := rhRecv(pConn, pBuff, len); err != nil {
  15. return -4, err
  16. }
  17. pBuff[len] = 0x0
  18. *valp = pBuff
  19. return 0, nil
  20. }
  21. // 接收单个字符
  22. func rhRecvChar(pConn *xugusqlConn, valp *byte) (bool, error) {
  23. var ch [1]byte
  24. err := rhRecv(pConn, ch[:], 1)
  25. if err != nil {
  26. return false, err
  27. }
  28. *valp = ch[0]
  29. return true, nil
  30. }
  31. // TODO : pConn.bkChar != 0x0 这一部分代码需要修改
  32. func rhRecv(pConn *xugusqlConn, buff []byte, dLen uint32) error {
  33. //old_len := dLen
  34. if pConn.bkChar != 0x0 {
  35. buff[0] = pConn.bkChar
  36. pConn.bkChar = 0x0
  37. buff = buff[1:]
  38. dLen--
  39. }
  40. //接收加密登录信息
  41. if dLen != 0 {
  42. for dLen != 0 {
  43. if pConn.useSSL {
  44. buffer := make([]byte, 1024)
  45. n, err := pConn.conn.Read(buffer)
  46. if err != nil {
  47. return err
  48. } else {
  49. xgCacheRecv(pConn, buffer, int32(n))
  50. }
  51. if n <= 0 {
  52. return errors.New("read error")
  53. }
  54. }
  55. }
  56. // DECRYPT(p_conn, buff, old_len); //解密缓冲
  57. }
  58. return nil
  59. }
  60. func rhRecvInt32(pconn *xugusqlConn, i *uint32) error {
  61. var buff [4]byte
  62. err := rhRecv(pconn, buff[:], 4)
  63. if err != nil {
  64. return err
  65. }
  66. // 将大端字节序转换为主机字节序
  67. *i = binary.BigEndian.Uint32(buff[:])
  68. return nil
  69. }
  70. func xgCacheRecv(pConn *xugusqlConn, buff []byte, dLen int32) (int, error) {
  71. return 0, nil
  72. }
  73. // 从连接中接收字段信息,并将其存储在 Result 结构体中。
  74. func recvFiledsInfo(pConn *xugusqlConn, pRes *Result) (int, error) {
  75. var fieldNum uint32
  76. //var pRet *FieldInfo
  77. if err := rhRecvInt32(pConn, &fieldNum); err != nil {
  78. return XG_NET_ERROR, err
  79. }
  80. if fieldNum > 4000 {
  81. return XG_NET_ERROR, errors.New("fieldNum >4000")
  82. }
  83. pRes.FieldNum = fieldNum
  84. pRet := make([]FieldInfo, fieldNum)
  85. //接收字段详细信息
  86. for n := uint32(0); n < fieldNum; n++ {
  87. if ret, err := recvAttrDesItem(pConn, &pRet[n]); err != nil {
  88. return ret, err
  89. }
  90. }
  91. bytesN := (fieldNum*2 + 7) / 8
  92. for n := uint32(0); n < fieldNum; n++ {
  93. pRet[n].Offset = bytesN
  94. bytesN += uint32(getSQLCType(pRet[n].TypeID))
  95. }
  96. // TODO : 这里需要重新修改
  97. // 在c代码中这里还加上了 ROW_HEAD_SIZE
  98. pRes.RowSize = bytesN + 24
  99. pRes.ColInfos = pRet
  100. return 0, nil
  101. }
  102. // 接收字段属性描述
  103. func recvAttrDesItem(pConn *xugusqlConn, pItem *FieldInfo) (int, error) {
  104. var nameLen uint32
  105. var tabName []byte
  106. var alias []byte
  107. if err := rhRecvInt32(pConn, &nameLen); err != nil {
  108. return XG_NET_ERROR, err
  109. }
  110. if nameLen > 1024 {
  111. return XG_NET_ERROR, errors.New("nameLen >1024")
  112. }
  113. var name []byte
  114. if err := rhRecv(pConn, name, nameLen); err != nil {
  115. return XG_NET_ERROR, err
  116. }
  117. if ret := bytes.IndexByte(name, '%'); ret != -1 {
  118. alias = name[ret+1:]
  119. name = name[:ret-1]
  120. }
  121. if ret := bytes.IndexByte(name, '.'); ret != -1 {
  122. //如果 return_schema_on 为真,那么这里将得到 schema_name.tab_name。
  123. tabName = name[:ret-1]
  124. name = name[ret+1:]
  125. }
  126. pItem.TabName = string(tabName)
  127. pItem.Name = string(name)
  128. pItem.Alias = string(alias)
  129. if err := rhRecvInt32(pConn, &pItem.TypeID); err != nil {
  130. return XG_NET_ERROR, err
  131. }
  132. if err := rhRecvInt32(pConn, &pItem.Modi); err != nil {
  133. return XG_NET_ERROR, err
  134. }
  135. if err := rhRecvInt32(pConn, &pItem.Flags); err != nil {
  136. return XG_NET_ERROR, err
  137. }
  138. pItem.CTypeID = uint32(getSQLCType(pItem.TypeID))
  139. return 0, nil
  140. }
  141. func recvParamsInfo2(pConn *xugusqlConn, params *XGCSParam) (int, error) {
  142. var paramNum uint32
  143. var i_ord []uint32
  144. var i_type []uint32
  145. var i_prescale []uint32
  146. pNames := make([][]byte, paramNum)
  147. rhRecvInt32(pConn, &paramNum)
  148. params.ParamNum = paramNum
  149. for n := uint32(0); n < paramNum; n++ {
  150. // 读取名称
  151. rhRecvStr(pConn, &pNames[n])
  152. // 读取序号
  153. rhRecvInt32(pConn, &i_ord[n])
  154. // 读取类型
  155. rhRecvInt32(pConn, &i_type[n])
  156. // 读取预缩放值
  157. rhRecvInt32(pConn, &i_prescale[n])
  158. }
  159. params.VParamName = pNames
  160. params.VParamNo = i_ord
  161. params.VType = i_type
  162. params.VParamSize = i_prescale
  163. return 0, nil
  164. }