convert.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // Copyright (c) 2012 The gocql Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package gocql
  5. import (
  6. "database/sql/driver"
  7. "encoding/binary"
  8. "fmt"
  9. "github.com/tux21b/gocql/uuid"
  10. "math"
  11. "strconv"
  12. "time"
  13. )
  14. const (
  15. typeCustom uint16 = 0x0000
  16. typeAscii uint16 = 0x0001
  17. typeBigInt uint16 = 0x0002
  18. typeBlob uint16 = 0x0003
  19. typeBool uint16 = 0x0004
  20. typeCounter uint16 = 0x0005
  21. typeDecimal uint16 = 0x0006
  22. typeDouble uint16 = 0x0007
  23. typeFloat uint16 = 0x0008
  24. typeInt uint16 = 0x0009
  25. typeText uint16 = 0x000A
  26. typeTimestamp uint16 = 0x000B
  27. typeUUID uint16 = 0x000C
  28. typeVarchar uint16 = 0x000D
  29. typeVarint uint16 = 0x000E
  30. typeTimeUUID uint16 = 0x000F
  31. typeList uint16 = 0x0020
  32. typeMap uint16 = 0x0021
  33. typeSet uint16 = 0x0022
  34. )
  35. func decode(b []byte, t uint16) driver.Value {
  36. switch t {
  37. case typeBool:
  38. if len(b) >= 1 && b[0] != 0 {
  39. return true
  40. }
  41. return false
  42. case typeBlob:
  43. return b
  44. case typeVarchar, typeText, typeAscii:
  45. return b
  46. case typeInt:
  47. return int64(int32(binary.BigEndian.Uint32(b)))
  48. case typeBigInt:
  49. return int64(binary.BigEndian.Uint64(b))
  50. case typeFloat:
  51. return float64(math.Float32frombits(binary.BigEndian.Uint32(b)))
  52. case typeDouble:
  53. return math.Float64frombits(binary.BigEndian.Uint64(b))
  54. case typeTimestamp:
  55. t := int64(binary.BigEndian.Uint64(b))
  56. sec := t / 1000
  57. nsec := (t - sec*1000) * 1000000
  58. return time.Unix(sec, nsec)
  59. case typeUUID, typeTimeUUID:
  60. return uuid.FromBytes(b)
  61. default:
  62. panic("unsupported type")
  63. }
  64. return b
  65. }
  66. type columnEncoder struct {
  67. columnTypes []uint16
  68. }
  69. func (e *columnEncoder) ColumnConverter(idx int) ValueConverter {
  70. switch e.columnTypes[idx] {
  71. case typeInt:
  72. return ValueConverter(encInt)
  73. case typeFloat:
  74. return ValueConverter(encFloat)
  75. case typeDouble:
  76. return ValueConverter(encDouble)
  77. case typeBool:
  78. return ValueConverter(encBool)
  79. case typeVarchar, typeText, typeAscii:
  80. return ValueConverter(encVarchar)
  81. case typeBlob:
  82. return ValueConverter(encBlob)
  83. case typeTimestamp:
  84. return ValueConverter(encTimestamp)
  85. case typeUUID, typeTimeUUID:
  86. return ValueConverter(encUUID)
  87. }
  88. panic("not implemented")
  89. }
  90. type ValueConverter func(v interface{}) (driver.Value, error)
  91. func (vc ValueConverter) ConvertValue(v interface{}) (driver.Value, error) {
  92. return vc(v)
  93. }
  94. func encBool(v interface{}) (driver.Value, error) {
  95. b, err := driver.Bool.ConvertValue(v)
  96. if err != nil {
  97. return nil, err
  98. }
  99. if b.(bool) {
  100. return []byte{1}, nil
  101. }
  102. return []byte{0}, nil
  103. }
  104. func encInt(v interface{}) (driver.Value, error) {
  105. x, err := driver.Int32.ConvertValue(v)
  106. if err != nil {
  107. return nil, err
  108. }
  109. b := make([]byte, 4)
  110. binary.BigEndian.PutUint32(b, uint32(x.(int64)))
  111. return b, nil
  112. }
  113. func encVarchar(v interface{}) (driver.Value, error) {
  114. x, err := driver.String.ConvertValue(v)
  115. if err != nil {
  116. return nil, err
  117. }
  118. return []byte(x.(string)), nil
  119. }
  120. func encFloat(v interface{}) (driver.Value, error) {
  121. x, err := driver.DefaultParameterConverter.ConvertValue(v)
  122. if err != nil {
  123. return nil, err
  124. }
  125. var f float64
  126. switch x := x.(type) {
  127. case float64:
  128. f = x
  129. case int64:
  130. f = float64(x)
  131. case []byte:
  132. if f, err = strconv.ParseFloat(string(x), 64); err != nil {
  133. return nil, err
  134. }
  135. default:
  136. return nil, fmt.Errorf("can not convert %T to float64", x)
  137. }
  138. b := make([]byte, 4)
  139. binary.BigEndian.PutUint32(b, math.Float32bits(float32(f)))
  140. return b, nil
  141. }
  142. func encDouble(v interface{}) (driver.Value, error) {
  143. x, err := driver.DefaultParameterConverter.ConvertValue(v)
  144. if err != nil {
  145. return nil, err
  146. }
  147. var f float64
  148. switch x := x.(type) {
  149. case float64:
  150. f = x
  151. case int64:
  152. f = float64(x)
  153. case []byte:
  154. if f, err = strconv.ParseFloat(string(x), 64); err != nil {
  155. return nil, err
  156. }
  157. default:
  158. return nil, fmt.Errorf("can not convert %T to float64", x)
  159. }
  160. b := make([]byte, 8)
  161. binary.BigEndian.PutUint64(b, math.Float64bits(f))
  162. return b, nil
  163. }
  164. func encTimestamp(v interface{}) (driver.Value, error) {
  165. x, err := driver.DefaultParameterConverter.ConvertValue(v)
  166. if err != nil {
  167. return nil, err
  168. }
  169. var millis int64
  170. switch x := x.(type) {
  171. case time.Time:
  172. x = x.In(time.UTC)
  173. millis = x.UnixNano() / 1000000
  174. default:
  175. return nil, fmt.Errorf("can not convert %T to a timestamp", x)
  176. }
  177. b := make([]byte, 8)
  178. binary.BigEndian.PutUint64(b, uint64(millis))
  179. return b, nil
  180. }
  181. func encBlob(v interface{}) (driver.Value, error) {
  182. x, err := driver.DefaultParameterConverter.ConvertValue(v)
  183. if err != nil {
  184. return nil, err
  185. }
  186. var b []byte
  187. switch x := x.(type) {
  188. case string:
  189. b = []byte(x)
  190. case []byte:
  191. b = x
  192. default:
  193. return nil, fmt.Errorf("can not convert %T to a []byte", x)
  194. }
  195. return b, nil
  196. }
  197. func encUUID(v interface{}) (driver.Value, error) {
  198. var u uuid.UUID
  199. switch v := v.(type) {
  200. case string:
  201. var err error
  202. u, err = uuid.ParseUUID(v)
  203. if err != nil {
  204. return nil, err
  205. }
  206. case []byte:
  207. u = uuid.FromBytes(v)
  208. case uuid.UUID:
  209. u = v
  210. default:
  211. return nil, fmt.Errorf("can not convert %T to a UUID", v)
  212. }
  213. return u.Bytes(), nil
  214. }