/Godeps/_workspace/src/github.com/ziutek/mymysql/mysql/row.go

https://gitlab.com/voxxit/gogeoip2 · Go · 475 lines · 366 code · 36 blank · 73 comment · 65 complexity · 45582726f84c0336ed41f0b9bf5a711d MD5 · raw file

  1. package mysql
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "math"
  7. "os"
  8. "reflect"
  9. "strconv"
  10. "time"
  11. )
  12. // Result row - contains values for any column of received row.
  13. //
  14. // If row is a result of ordinary text query, its element can be
  15. // []byte slice, contained result text or nil if NULL is returned.
  16. //
  17. // If it is result of prepared statement execution, its element field can be:
  18. // intX, uintX, floatX, []byte, Date, Time, time.Time (in Local location) or nil
  19. type Row []interface{}
  20. // Get the nn-th value and return it as []byte ([]byte{} if NULL)
  21. func (tr Row) Bin(nn int) (bin []byte) {
  22. switch data := tr[nn].(type) {
  23. case nil:
  24. // bin = []byte{}
  25. case []byte:
  26. bin = data
  27. default:
  28. buf := new(bytes.Buffer)
  29. fmt.Fprint(buf, data)
  30. bin = buf.Bytes()
  31. }
  32. return
  33. }
  34. // Get the nn-th value and return it as string ("" if NULL)
  35. func (tr Row) Str(nn int) (str string) {
  36. switch data := tr[nn].(type) {
  37. case nil:
  38. // str = ""
  39. case []byte:
  40. str = string(data)
  41. case time.Time:
  42. str = TimeString(data)
  43. case time.Duration:
  44. str = DurationString(data)
  45. default:
  46. str = fmt.Sprint(data)
  47. }
  48. return
  49. }
  50. const _MAX_INT = int64(int(^uint(0) >> 1))
  51. const _MIN_INT = -_MAX_INT - 1
  52. // Get the nn-th value and return it as int (0 if NULL). Return error if
  53. // conversion is impossible.
  54. func (tr Row) IntErr(nn int) (val int, err error) {
  55. switch data := tr[nn].(type) {
  56. case nil:
  57. // nop
  58. case int32:
  59. val = int(data)
  60. case int16:
  61. val = int(data)
  62. case uint16:
  63. val = int(data)
  64. case int8:
  65. val = int(data)
  66. case uint8:
  67. val = int(data)
  68. case []byte:
  69. val, err = strconv.Atoi(string(data))
  70. case int64:
  71. if data >= _MIN_INT && data <= _MAX_INT {
  72. val = int(data)
  73. } else {
  74. err = strconv.ErrRange
  75. }
  76. case uint32:
  77. if int64(data) <= _MAX_INT {
  78. val = int(data)
  79. } else {
  80. err = strconv.ErrRange
  81. }
  82. case uint64:
  83. if data <= uint64(_MAX_INT) {
  84. val = int(data)
  85. } else {
  86. err = strconv.ErrRange
  87. }
  88. default:
  89. err = os.ErrInvalid
  90. }
  91. return
  92. }
  93. // Get the nn-th value and return it as int (0 if NULL). Panic if conversion is
  94. // impossible.
  95. func (tr Row) Int(nn int) (val int) {
  96. val, err := tr.IntErr(nn)
  97. if err != nil {
  98. panic(err)
  99. }
  100. return
  101. }
  102. // Get the nn-th value and return it as int. Return 0 if value is NULL or
  103. // conversion is impossible.
  104. func (tr Row) ForceInt(nn int) (val int) {
  105. val, _ = tr.IntErr(nn)
  106. return
  107. }
  108. const _MAX_UINT = uint64(^uint(0))
  109. // Get the nn-th value and return it as uint (0 if NULL). Return error if
  110. // conversion is impossible.
  111. func (tr Row) UintErr(nn int) (val uint, err error) {
  112. switch data := tr[nn].(type) {
  113. case nil:
  114. // nop
  115. case uint32:
  116. val = uint(data)
  117. case uint16:
  118. val = uint(data)
  119. case uint8:
  120. val = uint(data)
  121. case []byte:
  122. var v uint64
  123. v, err = strconv.ParseUint(string(data), 0, 0)
  124. val = uint(v)
  125. case uint64:
  126. if data <= _MAX_UINT {
  127. val = uint(data)
  128. } else {
  129. err = strconv.ErrRange
  130. }
  131. case int8, int16, int32, int64:
  132. v := reflect.ValueOf(data).Int()
  133. if v >= 0 && uint64(v) <= _MAX_UINT {
  134. val = uint(v)
  135. } else {
  136. err = strconv.ErrRange
  137. }
  138. default:
  139. err = os.ErrInvalid
  140. }
  141. return
  142. }
  143. // Get the nn-th value and return it as uint (0 if NULL). Panic if conversion is
  144. // impossible.
  145. func (tr Row) Uint(nn int) (val uint) {
  146. val, err := tr.UintErr(nn)
  147. if err != nil {
  148. panic(err)
  149. }
  150. return
  151. }
  152. // Get the nn-th value and return it as uint. Return 0 if value is NULL or
  153. // conversion is impossible.
  154. func (tr Row) ForceUint(nn int) (val uint) {
  155. val, _ = tr.UintErr(nn)
  156. return
  157. }
  158. // Get the nn-th value and return it as Date (0000-00-00 if NULL). Return error
  159. // if conversion is impossible.
  160. func (tr Row) DateErr(nn int) (val Date, err error) {
  161. switch data := tr[nn].(type) {
  162. case nil:
  163. // nop
  164. case Date:
  165. val = data
  166. case []byte:
  167. val, err = ParseDate(string(data))
  168. }
  169. return
  170. }
  171. // It is like DateErr but panics if conversion is impossible.
  172. func (tr Row) Date(nn int) (val Date) {
  173. val, err := tr.DateErr(nn)
  174. if err != nil {
  175. panic(err)
  176. }
  177. return
  178. }
  179. // It is like DateErr but return 0000-00-00 if conversion is impossible.
  180. func (tr Row) ForceDate(nn int) (val Date) {
  181. val, _ = tr.DateErr(nn)
  182. return
  183. }
  184. // Get the nn-th value and return it as time.Time in loc location (zero if NULL)
  185. // Returns error if conversion is impossible. It can convert Date to time.Time.
  186. func (tr Row) TimeErr(nn int, loc *time.Location) (t time.Time, err error) {
  187. switch data := tr[nn].(type) {
  188. case nil:
  189. // nop
  190. case time.Time:
  191. if loc == time.Local {
  192. t = data
  193. } else {
  194. y, mon, d := data.Date()
  195. h, m, s := data.Clock()
  196. t = time.Date(y, mon, d, h, m, s, t.Nanosecond(), loc)
  197. }
  198. case Date:
  199. t = data.Time(loc)
  200. case []byte:
  201. t, err = ParseTime(string(data), loc)
  202. }
  203. return
  204. }
  205. // As TimeErr but panics if conversion is impossible.
  206. func (tr Row) Time(nn int, loc *time.Location) (val time.Time) {
  207. val, err := tr.TimeErr(nn, loc)
  208. if err != nil {
  209. panic(err)
  210. }
  211. return
  212. }
  213. // It is like TimeErr but returns 0000-00-00 00:00:00 if conversion is
  214. // impossible.
  215. func (tr Row) ForceTime(nn int, loc *time.Location) (val time.Time) {
  216. val, _ = tr.TimeErr(nn, loc)
  217. return
  218. }
  219. // Get the nn-th value and return it as time.Time in Local location
  220. // (zero if NULL). Returns error if conversion is impossible.
  221. // It can convert Date to time.Time.
  222. func (tr Row) LocaltimeErr(nn int) (t time.Time, err error) {
  223. switch data := tr[nn].(type) {
  224. case nil:
  225. // nop
  226. case time.Time:
  227. t = data
  228. case Date:
  229. t = data.Time(time.Local)
  230. case []byte:
  231. t, err = ParseTime(string(data), time.Local)
  232. }
  233. return
  234. }
  235. // As LocaltimeErr but panics if conversion is impossible.
  236. func (tr Row) Localtime(nn int) (val time.Time) {
  237. val, err := tr.LocaltimeErr(nn)
  238. if err != nil {
  239. panic(err)
  240. }
  241. return
  242. }
  243. // It is like LocaltimeErr but returns 0000-00-00 00:00:00 if conversion is
  244. // impossible.
  245. func (tr Row) ForceLocaltime(nn int) (val time.Time) {
  246. val, _ = tr.LocaltimeErr(nn)
  247. return
  248. }
  249. // Get the nn-th value and return it as time.Duration (0 if NULL). Return error
  250. // if conversion is impossible.
  251. func (tr Row) DurationErr(nn int) (val time.Duration, err error) {
  252. switch data := tr[nn].(type) {
  253. case nil:
  254. case time.Duration:
  255. val = data
  256. case []byte:
  257. val, err = ParseDuration(string(data))
  258. default:
  259. err = errors.New(
  260. fmt.Sprintf("Can't convert `%v` to time.Duration", data),
  261. )
  262. }
  263. return
  264. }
  265. // It is like DurationErr but panics if conversion is impossible.
  266. func (tr Row) Duration(nn int) (val time.Duration) {
  267. val, err := tr.DurationErr(nn)
  268. if err != nil {
  269. panic(err)
  270. }
  271. return
  272. }
  273. // It is like DurationErr but return 0 if conversion is impossible.
  274. func (tr Row) ForceDuration(nn int) (val time.Duration) {
  275. val, _ = tr.DurationErr(nn)
  276. return
  277. }
  278. // Get the nn-th value and return it as bool. Return error
  279. // if conversion is impossible.
  280. func (tr Row) BoolErr(nn int) (val bool, err error) {
  281. switch data := tr[nn].(type) {
  282. case nil:
  283. // nop
  284. case int8:
  285. val = (data != 0)
  286. case int32:
  287. val = (data != 0)
  288. case int16:
  289. val = (data != 0)
  290. case int64:
  291. val = (data != 0)
  292. case uint8:
  293. val = (data != 0)
  294. case uint32:
  295. val = (data != 0)
  296. case uint16:
  297. val = (data != 0)
  298. case uint64:
  299. val = (data != 0)
  300. case []byte:
  301. var v int64
  302. v, err = strconv.ParseInt(string(data), 0, 64)
  303. val = (v != 0)
  304. default:
  305. err = os.ErrInvalid
  306. }
  307. return
  308. }
  309. // It is like BoolErr but panics if conversion is impossible.
  310. func (tr Row) Bool(nn int) (val bool) {
  311. val, err := tr.BoolErr(nn)
  312. if err != nil {
  313. panic(err)
  314. }
  315. return
  316. }
  317. // It is like BoolErr but return false if conversion is impossible.
  318. func (tr Row) ForceBool(nn int) (val bool) {
  319. val, _ = tr.BoolErr(nn)
  320. return
  321. }
  322. // Get the nn-th value and return it as int64 (0 if NULL). Return error if
  323. // conversion is impossible.
  324. func (tr Row) Int64Err(nn int) (val int64, err error) {
  325. switch data := tr[nn].(type) {
  326. case nil:
  327. // nop
  328. case int64, int32, int16, int8:
  329. val = reflect.ValueOf(data).Int()
  330. case uint64, uint32, uint16, uint8:
  331. u := reflect.ValueOf(data).Uint()
  332. if u > math.MaxInt64 {
  333. err = strconv.ErrRange
  334. } else {
  335. val = int64(u)
  336. }
  337. case []byte:
  338. val, err = strconv.ParseInt(string(data), 10, 64)
  339. default:
  340. err = os.ErrInvalid
  341. }
  342. return
  343. }
  344. // Get the nn-th value and return it as int64 (0 if NULL).
  345. // Panic if conversion is impossible.
  346. func (tr Row) Int64(nn int) (val int64) {
  347. val, err := tr.Int64Err(nn)
  348. if err != nil {
  349. panic(err)
  350. }
  351. return
  352. }
  353. // Get the nn-th value and return it as int64. Return 0 if value is NULL or
  354. // conversion is impossible.
  355. func (tr Row) ForceInt64(nn int) (val int64) {
  356. val, _ = tr.Int64Err(nn)
  357. return
  358. }
  359. // Get the nn-th value and return it as uint64 (0 if NULL). Return error if
  360. // conversion is impossible.
  361. func (tr Row) Uint64Err(nn int) (val uint64, err error) {
  362. switch data := tr[nn].(type) {
  363. case nil:
  364. // nop
  365. case uint64, uint32, uint16, uint8:
  366. val = reflect.ValueOf(data).Uint()
  367. case int64, int32, int16, int8:
  368. i := reflect.ValueOf(data).Int()
  369. if i < 0 {
  370. err = strconv.ErrRange
  371. } else {
  372. val = uint64(i)
  373. }
  374. case []byte:
  375. val, err = strconv.ParseUint(string(data), 10, 64)
  376. default:
  377. err = os.ErrInvalid
  378. }
  379. return
  380. }
  381. // Get the nn-th value and return it as uint64 (0 if NULL).
  382. // Panic if conversion is impossible.
  383. func (tr Row) Uint64(nn int) (val uint64) {
  384. val, err := tr.Uint64Err(nn)
  385. if err != nil {
  386. panic(err)
  387. }
  388. return
  389. }
  390. // Get the nn-th value and return it as uint64. Return 0 if value is NULL or
  391. // conversion is impossible.
  392. func (tr Row) ForceUint64(nn int) (val uint64) {
  393. val, _ = tr.Uint64Err(nn)
  394. return
  395. }
  396. // Get the nn-th value and return it as float64 (0 if NULL). Return error if
  397. // conversion is impossible.
  398. func (tr Row) FloatErr(nn int) (val float64, err error) {
  399. switch data := tr[nn].(type) {
  400. case nil:
  401. // nop
  402. case float64, float32:
  403. val = reflect.ValueOf(data).Float()
  404. case int64, int32, int16, int8:
  405. i := reflect.ValueOf(data).Int()
  406. if i >= 2<<53 || i <= -(2<<53) {
  407. err = strconv.ErrRange
  408. } else {
  409. val = float64(i)
  410. }
  411. case uint64, uint32, uint16, uint8:
  412. u := reflect.ValueOf(data).Uint()
  413. if u >= 2<<53 {
  414. err = strconv.ErrRange
  415. } else {
  416. val = float64(u)
  417. }
  418. case []byte:
  419. val, err = strconv.ParseFloat(string(data), 64)
  420. default:
  421. err = os.ErrInvalid
  422. }
  423. return
  424. }
  425. // Get the nn-th value and return it as float64 (0 if NULL).
  426. // Panic if conversion is impossible.
  427. func (tr Row) Float(nn int) (val float64) {
  428. val, err := tr.FloatErr(nn)
  429. if err != nil {
  430. panic(err)
  431. }
  432. return
  433. }
  434. // Get the nn-th value and return it as float64. Return 0 if value is NULL or
  435. // if conversion is impossible.
  436. func (tr Row) ForceFloat(nn int) (val float64) {
  437. val, _ = tr.FloatErr(nn)
  438. return
  439. }