convert.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. // Copyright 2017 The Xorm 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 xorm
  5. import (
  6. "database/sql/driver"
  7. "errors"
  8. "fmt"
  9. "reflect"
  10. "strconv"
  11. "time"
  12. )
  13. var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
  14. func strconvErr(err error) error {
  15. if ne, ok := err.(*strconv.NumError); ok {
  16. return ne.Err
  17. }
  18. return err
  19. }
  20. func cloneBytes(b []byte) []byte {
  21. if b == nil {
  22. return nil
  23. } else {
  24. c := make([]byte, len(b))
  25. copy(c, b)
  26. return c
  27. }
  28. }
  29. func asString(src interface{}) string {
  30. switch v := src.(type) {
  31. case string:
  32. return v
  33. case []byte:
  34. return string(v)
  35. }
  36. rv := reflect.ValueOf(src)
  37. switch rv.Kind() {
  38. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  39. return strconv.FormatInt(rv.Int(), 10)
  40. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  41. return strconv.FormatUint(rv.Uint(), 10)
  42. case reflect.Float64:
  43. return strconv.FormatFloat(rv.Float(), 'g', -1, 64)
  44. case reflect.Float32:
  45. return strconv.FormatFloat(rv.Float(), 'g', -1, 32)
  46. case reflect.Bool:
  47. return strconv.FormatBool(rv.Bool())
  48. }
  49. return fmt.Sprintf("%v", src)
  50. }
  51. func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) {
  52. switch rv.Kind() {
  53. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  54. return strconv.AppendInt(buf, rv.Int(), 10), true
  55. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  56. return strconv.AppendUint(buf, rv.Uint(), 10), true
  57. case reflect.Float32:
  58. return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true
  59. case reflect.Float64:
  60. return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true
  61. case reflect.Bool:
  62. return strconv.AppendBool(buf, rv.Bool()), true
  63. case reflect.String:
  64. s := rv.String()
  65. return append(buf, s...), true
  66. }
  67. return
  68. }
  69. // convertAssign copies to dest the value in src, converting it if possible.
  70. // An error is returned if the copy would result in loss of information.
  71. // dest should be a pointer type.
  72. func convertAssign(dest, src interface{}) error {
  73. // Common cases, without reflect.
  74. switch s := src.(type) {
  75. case string:
  76. switch d := dest.(type) {
  77. case *string:
  78. if d == nil {
  79. return errNilPtr
  80. }
  81. *d = s
  82. return nil
  83. case *[]byte:
  84. if d == nil {
  85. return errNilPtr
  86. }
  87. *d = []byte(s)
  88. return nil
  89. }
  90. case []byte:
  91. switch d := dest.(type) {
  92. case *string:
  93. if d == nil {
  94. return errNilPtr
  95. }
  96. *d = string(s)
  97. return nil
  98. case *interface{}:
  99. if d == nil {
  100. return errNilPtr
  101. }
  102. *d = cloneBytes(s)
  103. return nil
  104. case *[]byte:
  105. if d == nil {
  106. return errNilPtr
  107. }
  108. *d = cloneBytes(s)
  109. return nil
  110. }
  111. case time.Time:
  112. switch d := dest.(type) {
  113. case *string:
  114. *d = s.Format(time.RFC3339Nano)
  115. return nil
  116. case *[]byte:
  117. if d == nil {
  118. return errNilPtr
  119. }
  120. *d = []byte(s.Format(time.RFC3339Nano))
  121. return nil
  122. }
  123. case nil:
  124. switch d := dest.(type) {
  125. case *interface{}:
  126. if d == nil {
  127. return errNilPtr
  128. }
  129. *d = nil
  130. return nil
  131. case *[]byte:
  132. if d == nil {
  133. return errNilPtr
  134. }
  135. *d = nil
  136. return nil
  137. }
  138. }
  139. var sv reflect.Value
  140. switch d := dest.(type) {
  141. case *string:
  142. sv = reflect.ValueOf(src)
  143. switch sv.Kind() {
  144. case reflect.Bool,
  145. reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
  146. reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
  147. reflect.Float32, reflect.Float64:
  148. *d = asString(src)
  149. return nil
  150. }
  151. case *[]byte:
  152. sv = reflect.ValueOf(src)
  153. if b, ok := asBytes(nil, sv); ok {
  154. *d = b
  155. return nil
  156. }
  157. case *bool:
  158. bv, err := driver.Bool.ConvertValue(src)
  159. if err == nil {
  160. *d = bv.(bool)
  161. }
  162. return err
  163. case *interface{}:
  164. *d = src
  165. return nil
  166. }
  167. dpv := reflect.ValueOf(dest)
  168. if dpv.Kind() != reflect.Ptr {
  169. return errors.New("destination not a pointer")
  170. }
  171. if dpv.IsNil() {
  172. return errNilPtr
  173. }
  174. if !sv.IsValid() {
  175. sv = reflect.ValueOf(src)
  176. }
  177. dv := reflect.Indirect(dpv)
  178. if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) {
  179. switch b := src.(type) {
  180. case []byte:
  181. dv.Set(reflect.ValueOf(cloneBytes(b)))
  182. default:
  183. dv.Set(sv)
  184. }
  185. return nil
  186. }
  187. if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) {
  188. dv.Set(sv.Convert(dv.Type()))
  189. return nil
  190. }
  191. switch dv.Kind() {
  192. case reflect.Ptr:
  193. if src == nil {
  194. dv.Set(reflect.Zero(dv.Type()))
  195. return nil
  196. } else {
  197. dv.Set(reflect.New(dv.Type().Elem()))
  198. return convertAssign(dv.Interface(), src)
  199. }
  200. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  201. s := asString(src)
  202. i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())
  203. if err != nil {
  204. err = strconvErr(err)
  205. return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
  206. }
  207. dv.SetInt(i64)
  208. return nil
  209. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  210. s := asString(src)
  211. u64, err := strconv.ParseUint(s, 10, dv.Type().Bits())
  212. if err != nil {
  213. err = strconvErr(err)
  214. return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
  215. }
  216. dv.SetUint(u64)
  217. return nil
  218. case reflect.Float32, reflect.Float64:
  219. s := asString(src)
  220. f64, err := strconv.ParseFloat(s, dv.Type().Bits())
  221. if err != nil {
  222. err = strconvErr(err)
  223. return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
  224. }
  225. dv.SetFloat(f64)
  226. return nil
  227. case reflect.String:
  228. dv.SetString(asString(src))
  229. return nil
  230. }
  231. return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest)
  232. }
  233. func asKind(vv reflect.Value, tp reflect.Type) (interface{}, error) {
  234. switch tp.Kind() {
  235. case reflect.Int64:
  236. return vv.Int(), nil
  237. case reflect.Int:
  238. return int(vv.Int()), nil
  239. case reflect.Int32:
  240. return int32(vv.Int()), nil
  241. case reflect.Int16:
  242. return int16(vv.Int()), nil
  243. case reflect.Int8:
  244. return int8(vv.Int()), nil
  245. case reflect.Uint64:
  246. return vv.Uint(), nil
  247. case reflect.Uint:
  248. return uint(vv.Uint()), nil
  249. case reflect.Uint32:
  250. return uint32(vv.Uint()), nil
  251. case reflect.Uint16:
  252. return uint16(vv.Uint()), nil
  253. case reflect.Uint8:
  254. return uint8(vv.Uint()), nil
  255. case reflect.String:
  256. return vv.String(), nil
  257. case reflect.Slice:
  258. if tp.Elem().Kind() == reflect.Uint8 {
  259. v, err := strconv.ParseInt(string(vv.Interface().([]byte)), 10, 64)
  260. if err != nil {
  261. return nil, err
  262. }
  263. return v, nil
  264. }
  265. }
  266. return nil, fmt.Errorf("unsupported primary key type: %v, %v", tp, vv)
  267. }
  268. func convertFloat(v interface{}) (float64, error) {
  269. switch v.(type) {
  270. case float32:
  271. return float64(v.(float32)), nil
  272. case float64:
  273. return v.(float64), nil
  274. case string:
  275. i, err := strconv.ParseFloat(v.(string), 64)
  276. if err != nil {
  277. return 0, err
  278. }
  279. return i, nil
  280. case []byte:
  281. i, err := strconv.ParseFloat(string(v.([]byte)), 64)
  282. if err != nil {
  283. return 0, err
  284. }
  285. return i, nil
  286. }
  287. return 0, fmt.Errorf("unsupported type: %v", v)
  288. }
  289. func convertInt(v interface{}) (int64, error) {
  290. switch v.(type) {
  291. case int:
  292. return int64(v.(int)), nil
  293. case int8:
  294. return int64(v.(int8)), nil
  295. case int16:
  296. return int64(v.(int16)), nil
  297. case int32:
  298. return int64(v.(int32)), nil
  299. case int64:
  300. return v.(int64), nil
  301. case []byte:
  302. i, err := strconv.ParseInt(string(v.([]byte)), 10, 64)
  303. if err != nil {
  304. return 0, err
  305. }
  306. return i, nil
  307. case string:
  308. i, err := strconv.ParseInt(v.(string), 10, 64)
  309. if err != nil {
  310. return 0, err
  311. }
  312. return i, nil
  313. }
  314. return 0, fmt.Errorf("unsupported type: %v", v)
  315. }