xugu_parse.go 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. package xugu
  2. import (
  3. "database/sql/driver"
  4. "encoding/binary"
  5. "fmt"
  6. "strings"
  7. )
  8. type ParseParam interface {
  9. // 转换参数数据类型
  10. assertParamType(driver.Value, int) error
  11. // 解析参数数量
  12. assertParamCount(string) int
  13. // 解析参数绑定类型(按参数名称绑定类型和按参数位置绑定类型)
  14. assertBindType(string) int
  15. // 解析参数名称
  16. assertParamName(string) error
  17. }
  18. // 辅助结构体
  19. // type xuguValue struct {
  20. // // 布尔值,如果值为 true,表示当前字段的数据类型是大对象数据类型
  21. // islob bool
  22. // // 一个 *C.char 类型的指针,通常指向要绑定的参数值的地址
  23. // value []byte
  24. // plob []byte
  25. // // length 通常指定要绑定的参数数据的实际长度
  26. // length []int
  27. // // buff 通常指定要绑定的参数数据的内存缓冲区大小
  28. // buffSize int
  29. // // 在参数绑定时,指定表中字段的数据类型
  30. // types int
  31. // // 返回代码
  32. // rcode int
  33. // }
  34. type xuguParse struct {
  35. // bind_type 用于标识参数绑定的类型。
  36. // 参数绑定类型包括按参数名称绑定和按参数占位符绑定
  37. bind_type int
  38. // param_count 用于指定在 SQL 语句中需要绑定的参数数量
  39. param_count int
  40. // 当参数绑定类型为按参数名称绑定时,param_names 是参数名称的集合
  41. param_names []byte
  42. //Val []xuguValue
  43. // 当参数绑定类型为按参数占位符绑定时,position 标识参数的位置
  44. position int
  45. }
  46. func (Parse *xuguParse) assertParamCount(query string) int {
  47. fmt.Println("----assertParamCount func 判断参数个数")
  48. if Parse.bind_type == 0 {
  49. Parse.bind_type = Parse.assertBindType(query)
  50. }
  51. fmt.Println("**Parse.bind_type is", Parse.bind_type)
  52. switch Parse.bind_type {
  53. case BIND_PARAM_BY_POS:
  54. Parse.param_count = strings.Count(query, "?")
  55. case BIND_PARAM_BY_NAME:
  56. fmt.Println(">case BIND_PARAM_BY_NAME")
  57. Parse.param_count = 0
  58. pos := 0
  59. phead := -1
  60. for {
  61. pos = strings.IndexByte(query[phead+1:], ':')
  62. if pos == -1 {
  63. break
  64. }
  65. pos += phead + 1
  66. tmp := pos
  67. for tmp > phead {
  68. tmp--
  69. if query[tmp] == ' ' {
  70. continue
  71. }
  72. if query[tmp] == ',' || query[tmp] == '(' {
  73. Parse.param_count++
  74. }
  75. break
  76. }
  77. phead = pos
  78. }
  79. }
  80. fmt.Println("**Parse.param_count", Parse.param_count)
  81. return Parse.param_count
  82. }
  83. func (Parse *xuguParse) assertBindType(query string) int {
  84. fmt.Println("-----(param *xuguParse) assertBindType 判断绑定类型")
  85. Parse.bind_type = strings.IndexByte(query, '?')
  86. if Parse.bind_type != -1 {
  87. fmt.Println("** 是大对象语句")
  88. return BIND_PARAM_BY_POS
  89. }
  90. fmt.Println("** 不是大对象语句")
  91. return BIND_PARAM_BY_NAME
  92. }
  93. func (param *xuguParse) assertParamType(dV driver.Value, pos int) error {
  94. fmt.Println("-----(param *xuguParse) assertParamType 判断参数类型")
  95. // var dest xuguValue
  96. // switch dV.(type) {
  97. // case int64:
  98. // srcv, ok := dV.(int64)
  99. // if !ok {
  100. // news := errorNews("int64")
  101. // return errors.New(news)
  102. // }
  103. // S := strconv.FormatInt(srcv, 10)
  104. // dest.value = C.CString(S)
  105. // dest.length = C.int(strings.Count(S, "") - 1)
  106. // dest.buff = dest.length + 1
  107. // dest.islob = false
  108. // dest.types = SQL_XG_C_CHAR
  109. // case float32:
  110. // srcv, ok := dV.(float64)
  111. // if !ok {
  112. // news := errorNews("float32")
  113. // return errors.New(news)
  114. // }
  115. // S := strconv.FormatFloat(srcv, 'f', 6, 64)
  116. // dest.value = C.CString(S)
  117. // dest.length = C.int(strings.Count(S, "") - 1)
  118. // dest.buff = dest.length + 1
  119. // dest.islob = false
  120. // dest.types = SQL_XG_C_CHAR
  121. // case float64:
  122. // srcv, ok := dV.(float64)
  123. // if !ok {
  124. // news := errorNews("float64")
  125. // return errors.New(news)
  126. // }
  127. // S := strconv.FormatFloat(srcv, 'f', 15, 64)
  128. // dest.value = C.CString(S)
  129. // dest.length = C.int(strings.Count(S, "") - 1)
  130. // dest.buff = dest.length + 1
  131. // dest.islob = false
  132. // dest.types = SQL_XG_C_CHAR
  133. // case bool:
  134. // srcv, ok := dV.(bool)
  135. // if !ok {
  136. // news := errorNews("bool")
  137. // return errors.New(news)
  138. // }
  139. // S := strconv.FormatBool(srcv)
  140. // dest.value = C.CString(S)
  141. // dest.length = C.int(strings.Count(S, "") - 1)
  142. // dest.buff = dest.length + 1
  143. // dest.islob = false
  144. // dest.types = SQL_XG_C_CHAR
  145. // case string:
  146. // srcv, ok := dV.(string)
  147. // if !ok {
  148. // news := errorNews("string")
  149. // return errors.New(news)
  150. // }
  151. // dest.value = C.CString(srcv)
  152. // dest.length = C.int(strings.Count(srcv, "") - 1)
  153. // dest.buff = dest.length + 1
  154. // dest.islob = false
  155. // dest.types = SQL_XG_C_CHAR
  156. // if dest.length == 0 {
  157. // dest.length = 1
  158. // }
  159. // case time.Time:
  160. // srcv, ok := dV.(time.Time)
  161. // if !ok {
  162. // news := errorNews("time.Time")
  163. // return errors.New(news)
  164. // }
  165. // tm := fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d",
  166. // srcv.Year(), int(srcv.Month()), srcv.Day(),
  167. // srcv.Hour(), srcv.Minute(), srcv.Second())
  168. // dest.value = C.CString(tm)
  169. // dest.length = C.int(strings.Count(tm, "") - 1)
  170. // dest.buff = dest.length + 1
  171. // dest.islob = false
  172. // dest.types = SQL_XG_C_CHAR
  173. // case []byte:
  174. // re := cgo_xgc_new_lob(&dest.plob)
  175. // if re < 0 {
  176. // return errors.New("Cannot create new large object")
  177. // }
  178. // srcv, ok := dV.([]byte)
  179. // if !ok {
  180. // news := errorNews("[]byte")
  181. // return errors.New(news)
  182. // }
  183. // cgo_xgc_put_lob_data(
  184. // &dest.plob,
  185. // unsafe.Pointer((*C.char)(unsafe.Pointer(&srcv[0]))),
  186. // len(srcv))
  187. // cgo_xgc_put_lob_data(&dest.plob, nil, -1)
  188. // dest.value = nil
  189. // dest.length = C.int(8)
  190. // dest.buff = C.int(8)
  191. // dest.islob = true
  192. // dest.types = SQL_XG_C_BLOB
  193. // case nil:
  194. // dest.value = C.CString("xugusql")
  195. // dest.length = 0
  196. // dest.buff = C.int(strings.Count("xugusql", ""))
  197. // dest.islob = false
  198. // dest.types = SQL_XG_C_CHAR
  199. // default:
  200. // /* OTHER DATA TYPE */
  201. // return errors.New("Unknown data type")
  202. // }
  203. // param.position = pos
  204. // param.Val = append(param.Val, dest)
  205. return nil
  206. }
  207. func (param *xuguParse) assertParamName(query string) error {
  208. fmt.Println("----(param *xuguParse) assertParamName 判断参数名")
  209. if param.param_count <= 0 {
  210. param.assertParamCount(query)
  211. }
  212. pos := 0
  213. phead := -1
  214. for true {
  215. pos = strings.IndexByte(query[phead+1:], ':')
  216. if pos == -1 {
  217. break
  218. }
  219. pos += phead + 1
  220. tmp := pos
  221. for tmp > phead {
  222. tmp--
  223. if query[tmp] == ' ' {
  224. continue
  225. }
  226. // Parse parameter positions bound by parameter name
  227. if query[tmp] == ',' || query[tmp] == '(' {
  228. parg := pos
  229. for true {
  230. parg++
  231. if query[parg] == ',' || query[parg] == ')' || query[parg] == ' ' {
  232. param.param_names = append(param.param_names, query[pos+1:parg]...)
  233. break
  234. }
  235. }
  236. }
  237. break
  238. }
  239. phead = pos
  240. }
  241. return nil
  242. }
  243. type SelectResult struct {
  244. Field_Num uint32
  245. Fields []FieldDescri
  246. Values [][]ValueData //[字段][字段所有值]
  247. }
  248. type FieldDescri struct {
  249. FieldNameLen int
  250. FieldName string
  251. FieldType fieldType
  252. FieldPreciScale int
  253. FieldFlag int
  254. }
  255. type ValueData struct {
  256. Col_len uint32
  257. Col_Data []byte
  258. }
  259. func parseSelectResult(readBuf buffer) (*SelectResult, error) {
  260. data := &SelectResult{}
  261. char := readBuf.peekChar()
  262. fmt.Println("--=char: ", string(char))
  263. switch char {
  264. case 'A':
  265. readBuf.idx++
  266. //Field_Num
  267. Field_Num := binary.BigEndian.Uint32(readBuf.readNext(4))
  268. data.Field_Num = Field_Num
  269. fmt.Println("Field_Num: ", data.Field_Num)
  270. //获取字段信息
  271. for i := 0; i < int(Field_Num); i++ {
  272. field := FieldDescri{}
  273. //Field_Name_Len
  274. field.FieldNameLen = int(binary.BigEndian.Uint32(readBuf.readNext(4)))
  275. fmt.Println("FieldNameLen: ", field.FieldNameLen)
  276. //Field_Name:
  277. field.FieldName = string(readBuf.readNext(field.FieldNameLen))
  278. fmt.Println("FieldName: ", field.FieldName)
  279. //Field_DType:
  280. field.FieldType = fieldType(binary.BigEndian.Uint32(readBuf.readNext(4)))
  281. fmt.Println("FieldType: ", field.FieldType)
  282. //Field_Preci_Scale:
  283. field.FieldPreciScale = int(binary.BigEndian.Uint32(readBuf.readNext(4)))
  284. fmt.Println("FieldPreciScale: ", field.FieldPreciScale)
  285. //Field_Flag:
  286. field.FieldFlag = int(binary.BigEndian.Uint32(readBuf.readNext(4)))
  287. fmt.Println("FieldFlag: ", field.FieldFlag)
  288. data.Fields = append(data.Fields, field)
  289. }
  290. fmt.Println("data的字段总数: ", data.Field_Num)
  291. for i, v := range data.Fields {
  292. fmt.Println("data的内容: ", i, v.FieldName)
  293. }
  294. data.Values = make([][]ValueData, data.Field_Num)
  295. //获取字段的行值
  296. // 使用 Peek 方法检查下一个字节是否为'R'或'K'
  297. char := readBuf.peekChar()
  298. fmt.Println("是否为R: ", string(char))
  299. readBuf.idx++
  300. if char == 'K' {
  301. break
  302. } else if char == 'R' {
  303. colIdx := 0
  304. for {
  305. col := ValueData{}
  306. col.Col_len = binary.BigEndian.Uint32(readBuf.readNext(4))
  307. // fmt.Println("Col_len: ", col.Col_len)
  308. col.Col_Data = readBuf.readNext(int(col.Col_len))
  309. fmt.Println("Col_Data: ", string(col.Col_Data))
  310. data.Values[colIdx] = append(data.Values[colIdx], col)
  311. colIdx++
  312. char := readBuf.peekChar()
  313. if char == 'R' {
  314. fmt.Println("--=char3: ", string(readBuf.peekChar()))
  315. readBuf.idx++
  316. colIdx = 0
  317. continue
  318. } else if char == 'K' {
  319. fmt.Println("--=char4: ", string(readBuf.peekChar()))
  320. break
  321. }
  322. }
  323. } else {
  324. break
  325. }
  326. }
  327. fmt.Println("data的内容: ", data)
  328. for i := 0; i < int(data.Field_Num); i++ {
  329. for j := 0; j < len(data.Values[i]); j++ {
  330. fmt.Printf("data.Values[%d]: %v\n", i, (data.Values[i][j].Col_Data))
  331. }
  332. }
  333. return data, nil
  334. }
  335. func parseInsertResult(readBuf buffer) (*SelectResult, error) {
  336. }