string.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. package types
  2. import (
  3. "database/sql"
  4. "database/sql/driver"
  5. "errors"
  6. "fmt"
  7. "reflect"
  8. "strconv"
  9. "time"
  10. )
  11. // TextNull is an implementation of a string for the MySQL type char/varchar/text ....
  12. type TextNull string
  13. // Value implements the driver.Valuer interface,
  14. // and turns the string into a bytes for MySQL storage.
  15. func (s TextNull) Value() (driver.Value, error) {
  16. return []byte(s), nil
  17. }
  18. // Scan implements the sql.Scanner interface,
  19. // and turns the bytes incoming from MySQL into a string
  20. func (s *TextNull) Scan(src interface{}) error {
  21. switch t := src.(type) {
  22. case string:
  23. *s = TextNull(src.(string))
  24. case []byte:
  25. if len(t) == 0 {
  26. *s = TextNull("")
  27. } else {
  28. *s = TextNull(src.([]byte))
  29. }
  30. case nil:
  31. *s = TextNull("")
  32. default:
  33. return errors.New("bad []byte type assertion")
  34. }
  35. return nil
  36. /*
  37. if src != nil {
  38. v, ok := src.([]byte)
  39. if !ok {
  40. return errors.New("bad []byte type assertion")
  41. }
  42. *s = TextNull(v)
  43. return nil
  44. }
  45. *s = TextNull("")
  46. return nil
  47. //*/
  48. }
  49. var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
  50. // convertAssign is the same as convertAssignRows, but without the optional
  51. // rows argument.
  52. func convertAssign(dest, src interface{}) error {
  53. return convertAssignRows(dest, src)
  54. }
  55. // convertAssignRows copies to dest the value in src, converting it if possible.
  56. // An error is returned if the copy would result in loss of information.
  57. // dest should be a pointer type. If rows is passed in, the rows will
  58. // be used as the parent for any cursor values converted from a
  59. // driver.Rows to a *Rows.
  60. func convertAssignRows(dest, src interface{}) error {
  61. // Common cases, without reflect.
  62. switch s := src.(type) {
  63. case string:
  64. switch d := dest.(type) {
  65. case *string:
  66. if d == nil {
  67. return errNilPtr
  68. }
  69. *d = s
  70. return nil
  71. case *[]byte:
  72. if d == nil {
  73. return errNilPtr
  74. }
  75. *d = []byte(s)
  76. return nil
  77. case *sql.RawBytes:
  78. if d == nil {
  79. return errNilPtr
  80. }
  81. *d = append((*d)[:0], s...)
  82. return nil
  83. }
  84. case []byte:
  85. switch d := dest.(type) {
  86. case *string:
  87. if d == nil {
  88. return errNilPtr
  89. }
  90. *d = string(s)
  91. return nil
  92. case *interface{}:
  93. if d == nil {
  94. return errNilPtr
  95. }
  96. *d = cloneBytes(s)
  97. return nil
  98. case *[]byte:
  99. if d == nil {
  100. return errNilPtr
  101. }
  102. *d = cloneBytes(s)
  103. return nil
  104. case *sql.RawBytes:
  105. if d == nil {
  106. return errNilPtr
  107. }
  108. *d = s
  109. return nil
  110. }
  111. case time.Time:
  112. switch d := dest.(type) {
  113. case *time.Time:
  114. *d = s
  115. return nil
  116. case *string:
  117. *d = s.Format(time.RFC3339Nano)
  118. return nil
  119. case *[]byte:
  120. if d == nil {
  121. return errNilPtr
  122. }
  123. *d = []byte(s.Format(time.RFC3339Nano))
  124. return nil
  125. case *sql.RawBytes:
  126. if d == nil {
  127. return errNilPtr
  128. }
  129. *d = s.AppendFormat((*d)[:0], time.RFC3339Nano)
  130. return nil
  131. }
  132. case nil:
  133. switch d := dest.(type) {
  134. case *interface{}:
  135. if d == nil {
  136. return errNilPtr
  137. }
  138. *d = nil
  139. return nil
  140. case *[]byte:
  141. if d == nil {
  142. return errNilPtr
  143. }
  144. *d = nil
  145. return nil
  146. case *sql.RawBytes:
  147. if d == nil {
  148. return errNilPtr
  149. }
  150. *d = nil
  151. return nil
  152. }
  153. // The driver is returning a cursor the client may iterate over.
  154. case driver.Rows:
  155. switch d := dest.(type) {
  156. case *sql.Rows:
  157. if d == nil {
  158. return errNilPtr
  159. }
  160. return nil
  161. }
  162. }
  163. var sv reflect.Value
  164. switch d := dest.(type) {
  165. case *string:
  166. sv = reflect.ValueOf(src)
  167. switch sv.Kind() {
  168. case reflect.Bool,
  169. reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
  170. reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
  171. reflect.Float32, reflect.Float64:
  172. *d = asString(src)
  173. return nil
  174. }
  175. case *[]byte:
  176. sv = reflect.ValueOf(src)
  177. if b, ok := asBytes(nil, sv); ok {
  178. *d = b
  179. return nil
  180. }
  181. case *sql.RawBytes:
  182. sv = reflect.ValueOf(src)
  183. if b, ok := asBytes([]byte(*d)[:0], sv); ok {
  184. *d = sql.RawBytes(b)
  185. return nil
  186. }
  187. case *bool:
  188. bv, err := driver.Bool.ConvertValue(src)
  189. if err == nil {
  190. *d = bv.(bool)
  191. }
  192. return err
  193. case *interface{}:
  194. *d = src
  195. return nil
  196. }
  197. return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest)
  198. }
  199. func cloneBytes(b []byte) []byte {
  200. if b == nil {
  201. return nil
  202. }
  203. c := make([]byte, len(b))
  204. copy(c, b)
  205. return c
  206. }
  207. func asString(src interface{}) string {
  208. switch v := src.(type) {
  209. case string:
  210. return v
  211. case []byte:
  212. return string(v)
  213. }
  214. rv := reflect.ValueOf(src)
  215. switch rv.Kind() {
  216. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  217. return strconv.FormatInt(rv.Int(), 10)
  218. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  219. return strconv.FormatUint(rv.Uint(), 10)
  220. case reflect.Float64:
  221. return strconv.FormatFloat(rv.Float(), 'g', -1, 64)
  222. case reflect.Float32:
  223. return strconv.FormatFloat(rv.Float(), 'g', -1, 32)
  224. case reflect.Bool:
  225. return strconv.FormatBool(rv.Bool())
  226. }
  227. return fmt.Sprintf("%v", src)
  228. }
  229. func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) {
  230. switch rv.Kind() {
  231. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  232. return strconv.AppendInt(buf, rv.Int(), 10), true
  233. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  234. return strconv.AppendUint(buf, rv.Uint(), 10), true
  235. case reflect.Float32:
  236. return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true
  237. case reflect.Float64:
  238. return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true
  239. case reflect.Bool:
  240. return strconv.AppendBool(buf, rv.Bool()), true
  241. case reflect.String:
  242. s := rv.String()
  243. return append(buf, s...), true
  244. }
  245. return
  246. }