resultset.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. package mysql
  2. import (
  3. "fmt"
  4. "strconv"
  5. "github.com/juju/errors"
  6. "github.com/siddontang/go/hack"
  7. )
  8. type RowData []byte
  9. func (p RowData) Parse(f []*Field, binary bool) ([]interface{}, error) {
  10. if binary {
  11. return p.ParseBinary(f)
  12. } else {
  13. return p.ParseText(f)
  14. }
  15. }
  16. func (p RowData) ParseText(f []*Field) ([]interface{}, error) {
  17. data := make([]interface{}, len(f))
  18. var err error
  19. var v []byte
  20. var isNull bool
  21. var pos int = 0
  22. var n int = 0
  23. for i := range f {
  24. v, isNull, n, err = LengthEnodedString(p[pos:])
  25. if err != nil {
  26. return nil, errors.Trace(err)
  27. }
  28. pos += n
  29. if isNull {
  30. data[i] = nil
  31. } else {
  32. isUnsigned := f[i].Flag&UNSIGNED_FLAG != 0
  33. switch f[i].Type {
  34. case MYSQL_TYPE_TINY, MYSQL_TYPE_SHORT, MYSQL_TYPE_INT24,
  35. MYSQL_TYPE_LONGLONG, MYSQL_TYPE_YEAR:
  36. if isUnsigned {
  37. data[i], err = strconv.ParseUint(string(v), 10, 64)
  38. } else {
  39. data[i], err = strconv.ParseInt(string(v), 10, 64)
  40. }
  41. case MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE:
  42. data[i], err = strconv.ParseFloat(string(v), 64)
  43. default:
  44. data[i] = v
  45. }
  46. if err != nil {
  47. return nil, errors.Trace(err)
  48. }
  49. }
  50. }
  51. return data, nil
  52. }
  53. func (p RowData) ParseBinary(f []*Field) ([]interface{}, error) {
  54. data := make([]interface{}, len(f))
  55. if p[0] != OK_HEADER {
  56. return nil, ErrMalformPacket
  57. }
  58. pos := 1 + ((len(f) + 7 + 2) >> 3)
  59. nullBitmap := p[1:pos]
  60. var isNull bool
  61. var n int
  62. var err error
  63. var v []byte
  64. for i := range data {
  65. if nullBitmap[(i+2)/8]&(1<<(uint(i+2)%8)) > 0 {
  66. data[i] = nil
  67. continue
  68. }
  69. isUnsigned := f[i].Flag&UNSIGNED_FLAG != 0
  70. switch f[i].Type {
  71. case MYSQL_TYPE_NULL:
  72. data[i] = nil
  73. continue
  74. case MYSQL_TYPE_TINY:
  75. if isUnsigned {
  76. data[i] = ParseBinaryUint8(p[pos : pos+1])
  77. } else {
  78. data[i] = ParseBinaryInt8(p[pos : pos+1])
  79. }
  80. pos++
  81. continue
  82. case MYSQL_TYPE_SHORT, MYSQL_TYPE_YEAR:
  83. if isUnsigned {
  84. data[i] = ParseBinaryUint16(p[pos : pos+2])
  85. } else {
  86. data[i] = ParseBinaryInt16(p[pos : pos+2])
  87. }
  88. pos += 2
  89. continue
  90. case MYSQL_TYPE_INT24:
  91. if isUnsigned {
  92. data[i] = ParseBinaryUint24(p[pos : pos+3])
  93. } else {
  94. data[i] = ParseBinaryInt24(p[pos : pos+3])
  95. }
  96. pos += 4
  97. continue
  98. case MYSQL_TYPE_LONG:
  99. if isUnsigned {
  100. data[i] = ParseBinaryUint32(p[pos : pos+4])
  101. } else {
  102. data[i] = ParseBinaryInt32(p[pos : pos+4])
  103. }
  104. pos += 4
  105. continue
  106. case MYSQL_TYPE_LONGLONG:
  107. if isUnsigned {
  108. data[i] = ParseBinaryUint64(p[pos : pos+8])
  109. } else {
  110. data[i] = ParseBinaryInt64(p[pos : pos+8])
  111. }
  112. pos += 8
  113. continue
  114. case MYSQL_TYPE_FLOAT:
  115. data[i] = ParseBinaryFloat32(p[pos : pos+4])
  116. pos += 4
  117. continue
  118. case MYSQL_TYPE_DOUBLE:
  119. data[i] = ParseBinaryFloat64(p[pos : pos+8])
  120. pos += 8
  121. continue
  122. case MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR,
  123. MYSQL_TYPE_BIT, MYSQL_TYPE_ENUM, MYSQL_TYPE_SET, MYSQL_TYPE_TINY_BLOB,
  124. MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
  125. MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_STRING, MYSQL_TYPE_GEOMETRY:
  126. v, isNull, n, err = LengthEnodedString(p[pos:])
  127. pos += n
  128. if err != nil {
  129. return nil, errors.Trace(err)
  130. }
  131. if !isNull {
  132. data[i] = v
  133. continue
  134. } else {
  135. data[i] = nil
  136. continue
  137. }
  138. case MYSQL_TYPE_DATE, MYSQL_TYPE_NEWDATE:
  139. var num uint64
  140. num, isNull, n = LengthEncodedInt(p[pos:])
  141. pos += n
  142. if isNull {
  143. data[i] = nil
  144. continue
  145. }
  146. data[i], err = FormatBinaryDate(int(num), p[pos:])
  147. pos += int(num)
  148. if err != nil {
  149. return nil, errors.Trace(err)
  150. }
  151. case MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_DATETIME:
  152. var num uint64
  153. num, isNull, n = LengthEncodedInt(p[pos:])
  154. pos += n
  155. if isNull {
  156. data[i] = nil
  157. continue
  158. }
  159. data[i], err = FormatBinaryDateTime(int(num), p[pos:])
  160. pos += int(num)
  161. if err != nil {
  162. return nil, errors.Trace(err)
  163. }
  164. case MYSQL_TYPE_TIME:
  165. var num uint64
  166. num, isNull, n = LengthEncodedInt(p[pos:])
  167. pos += n
  168. if isNull {
  169. data[i] = nil
  170. continue
  171. }
  172. data[i], err = FormatBinaryTime(int(num), p[pos:])
  173. pos += int(num)
  174. if err != nil {
  175. return nil, errors.Trace(err)
  176. }
  177. default:
  178. return nil, errors.Errorf("Stmt Unknown FieldType %d %s", f[i].Type, f[i].Name)
  179. }
  180. }
  181. return data, nil
  182. }
  183. type Resultset struct {
  184. Fields []*Field
  185. FieldNames map[string]int
  186. Values [][]interface{}
  187. RowDatas []RowData
  188. }
  189. func (r *Resultset) RowNumber() int {
  190. return len(r.Values)
  191. }
  192. func (r *Resultset) ColumnNumber() int {
  193. return len(r.Fields)
  194. }
  195. func (r *Resultset) GetValue(row, column int) (interface{}, error) {
  196. if row >= len(r.Values) || row < 0 {
  197. return nil, errors.Errorf("invalid row index %d", row)
  198. }
  199. if column >= len(r.Fields) || column < 0 {
  200. return nil, errors.Errorf("invalid column index %d", column)
  201. }
  202. return r.Values[row][column], nil
  203. }
  204. func (r *Resultset) NameIndex(name string) (int, error) {
  205. if column, ok := r.FieldNames[name]; ok {
  206. return column, nil
  207. } else {
  208. return 0, errors.Errorf("invalid field name %s", name)
  209. }
  210. }
  211. func (r *Resultset) GetValueByName(row int, name string) (interface{}, error) {
  212. if column, err := r.NameIndex(name); err != nil {
  213. return nil, errors.Trace(err)
  214. } else {
  215. return r.GetValue(row, column)
  216. }
  217. }
  218. func (r *Resultset) IsNull(row, column int) (bool, error) {
  219. d, err := r.GetValue(row, column)
  220. if err != nil {
  221. return false, err
  222. }
  223. return d == nil, nil
  224. }
  225. func (r *Resultset) IsNullByName(row int, name string) (bool, error) {
  226. if column, err := r.NameIndex(name); err != nil {
  227. return false, err
  228. } else {
  229. return r.IsNull(row, column)
  230. }
  231. }
  232. func (r *Resultset) GetUint(row, column int) (uint64, error) {
  233. d, err := r.GetValue(row, column)
  234. if err != nil {
  235. return 0, err
  236. }
  237. switch v := d.(type) {
  238. case int:
  239. return uint64(v), nil
  240. case int8:
  241. return uint64(v), nil
  242. case int16:
  243. return uint64(v), nil
  244. case int32:
  245. return uint64(v), nil
  246. case int64:
  247. return uint64(v), nil
  248. case uint:
  249. return uint64(v), nil
  250. case uint8:
  251. return uint64(v), nil
  252. case uint16:
  253. return uint64(v), nil
  254. case uint32:
  255. return uint64(v), nil
  256. case uint64:
  257. return uint64(v), nil
  258. case float32:
  259. return uint64(v), nil
  260. case float64:
  261. return uint64(v), nil
  262. case string:
  263. return strconv.ParseUint(v, 10, 64)
  264. case []byte:
  265. return strconv.ParseUint(string(v), 10, 64)
  266. case nil:
  267. return 0, nil
  268. default:
  269. return 0, errors.Errorf("data type is %T", v)
  270. }
  271. }
  272. func (r *Resultset) GetUintByName(row int, name string) (uint64, error) {
  273. if column, err := r.NameIndex(name); err != nil {
  274. return 0, err
  275. } else {
  276. return r.GetUint(row, column)
  277. }
  278. }
  279. func (r *Resultset) GetInt(row, column int) (int64, error) {
  280. v, err := r.GetUint(row, column)
  281. if err != nil {
  282. return 0, err
  283. }
  284. return int64(v), nil
  285. }
  286. func (r *Resultset) GetIntByName(row int, name string) (int64, error) {
  287. v, err := r.GetUintByName(row, name)
  288. if err != nil {
  289. return 0, err
  290. }
  291. return int64(v), nil
  292. }
  293. func (r *Resultset) GetFloat(row, column int) (float64, error) {
  294. d, err := r.GetValue(row, column)
  295. if err != nil {
  296. return 0, err
  297. }
  298. switch v := d.(type) {
  299. case int:
  300. return float64(v), nil
  301. case int8:
  302. return float64(v), nil
  303. case int16:
  304. return float64(v), nil
  305. case int32:
  306. return float64(v), nil
  307. case int64:
  308. return float64(v), nil
  309. case uint:
  310. return float64(v), nil
  311. case uint8:
  312. return float64(v), nil
  313. case uint16:
  314. return float64(v), nil
  315. case uint32:
  316. return float64(v), nil
  317. case uint64:
  318. return float64(v), nil
  319. case float32:
  320. return float64(v), nil
  321. case float64:
  322. return v, nil
  323. case string:
  324. return strconv.ParseFloat(v, 64)
  325. case []byte:
  326. return strconv.ParseFloat(string(v), 64)
  327. case nil:
  328. return 0, nil
  329. default:
  330. return 0, errors.Errorf("data type is %T", v)
  331. }
  332. }
  333. func (r *Resultset) GetFloatByName(row int, name string) (float64, error) {
  334. if column, err := r.NameIndex(name); err != nil {
  335. return 0, err
  336. } else {
  337. return r.GetFloat(row, column)
  338. }
  339. }
  340. func (r *Resultset) GetString(row, column int) (string, error) {
  341. d, err := r.GetValue(row, column)
  342. if err != nil {
  343. return "", err
  344. }
  345. switch v := d.(type) {
  346. case string:
  347. return v, nil
  348. case []byte:
  349. return hack.String(v), nil
  350. case int, int8, int16, int32, int64,
  351. uint, uint8, uint16, uint32, uint64:
  352. return fmt.Sprintf("%d", v), nil
  353. case float32:
  354. return strconv.FormatFloat(float64(v), 'f', -1, 64), nil
  355. case float64:
  356. return strconv.FormatFloat(v, 'f', -1, 64), nil
  357. case nil:
  358. return "", nil
  359. default:
  360. return "", errors.Errorf("data type is %T", v)
  361. }
  362. }
  363. func (r *Resultset) GetStringByName(row int, name string) (string, error) {
  364. if column, err := r.NameIndex(name); err != nil {
  365. return "", err
  366. } else {
  367. return r.GetString(row, column)
  368. }
  369. }