You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

671 lines
20 KiB

  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"
  7. "database/sql/driver"
  8. "errors"
  9. "fmt"
  10. "reflect"
  11. "strconv"
  12. "strings"
  13. "time"
  14. "xorm.io/core"
  15. )
  16. func (session *Session) str2Time(col *core.Column, data string) (outTime time.Time, outErr error) {
  17. sdata := strings.TrimSpace(data)
  18. var x time.Time
  19. var err error
  20. var parseLoc = session.engine.DatabaseTZ
  21. if col.TimeZone != nil {
  22. parseLoc = col.TimeZone
  23. }
  24. if sdata == zeroTime0 || sdata == zeroTime1 {
  25. } else if !strings.ContainsAny(sdata, "- :") { // !nashtsai! has only found that mymysql driver is using this for time type column
  26. // time stamp
  27. sd, err := strconv.ParseInt(sdata, 10, 64)
  28. if err == nil {
  29. x = time.Unix(sd, 0)
  30. //session.engine.logger.Debugf("time(0) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  31. } else {
  32. //session.engine.logger.Debugf("time(0) err key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  33. }
  34. } else if len(sdata) > 19 && strings.Contains(sdata, "-") {
  35. x, err = time.ParseInLocation(time.RFC3339Nano, sdata, parseLoc)
  36. session.engine.logger.Debugf("time(1) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  37. if err != nil {
  38. x, err = time.ParseInLocation("2006-01-02 15:04:05.999999999", sdata, parseLoc)
  39. //session.engine.logger.Debugf("time(2) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  40. }
  41. if err != nil {
  42. x, err = time.ParseInLocation("2006-01-02 15:04:05.9999999 Z07:00", sdata, parseLoc)
  43. //session.engine.logger.Debugf("time(3) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  44. }
  45. } else if len(sdata) == 19 && strings.Contains(sdata, "-") {
  46. x, err = time.ParseInLocation("2006-01-02 15:04:05", sdata, parseLoc)
  47. //session.engine.logger.Debugf("time(4) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  48. } else if len(sdata) == 10 && sdata[4] == '-' && sdata[7] == '-' {
  49. x, err = time.ParseInLocation("2006-01-02", sdata, parseLoc)
  50. //session.engine.logger.Debugf("time(5) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  51. } else if col.SQLType.Name == core.Time {
  52. if strings.Contains(sdata, " ") {
  53. ssd := strings.Split(sdata, " ")
  54. sdata = ssd[1]
  55. }
  56. sdata = strings.TrimSpace(sdata)
  57. if session.engine.dialect.DBType() == core.MYSQL && len(sdata) > 8 {
  58. sdata = sdata[len(sdata)-8:]
  59. }
  60. st := fmt.Sprintf("2006-01-02 %v", sdata)
  61. x, err = time.ParseInLocation("2006-01-02 15:04:05", st, parseLoc)
  62. //session.engine.logger.Debugf("time(6) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  63. } else {
  64. outErr = fmt.Errorf("unsupported time format %v", sdata)
  65. return
  66. }
  67. if err != nil {
  68. outErr = fmt.Errorf("unsupported time format %v: %v", sdata, err)
  69. return
  70. }
  71. outTime = x.In(session.engine.TZLocation)
  72. return
  73. }
  74. func (session *Session) byte2Time(col *core.Column, data []byte) (outTime time.Time, outErr error) {
  75. return session.str2Time(col, string(data))
  76. }
  77. var (
  78. nullFloatType = reflect.TypeOf(sql.NullFloat64{})
  79. )
  80. // convert a db data([]byte) to a field value
  81. func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value, data []byte) error {
  82. if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok {
  83. return structConvert.FromDB(data)
  84. }
  85. if structConvert, ok := fieldValue.Interface().(core.Conversion); ok {
  86. return structConvert.FromDB(data)
  87. }
  88. var v interface{}
  89. key := col.Name
  90. fieldType := fieldValue.Type()
  91. switch fieldType.Kind() {
  92. case reflect.Complex64, reflect.Complex128:
  93. x := reflect.New(fieldType)
  94. if len(data) > 0 {
  95. err := DefaultJSONHandler.Unmarshal(data, x.Interface())
  96. if err != nil {
  97. session.engine.logger.Error(err)
  98. return err
  99. }
  100. fieldValue.Set(x.Elem())
  101. }
  102. case reflect.Slice, reflect.Array, reflect.Map:
  103. v = data
  104. t := fieldType.Elem()
  105. k := t.Kind()
  106. if col.SQLType.IsText() {
  107. x := reflect.New(fieldType)
  108. if len(data) > 0 {
  109. err := DefaultJSONHandler.Unmarshal(data, x.Interface())
  110. if err != nil {
  111. session.engine.logger.Error(err)
  112. return err
  113. }
  114. fieldValue.Set(x.Elem())
  115. }
  116. } else if col.SQLType.IsBlob() {
  117. if k == reflect.Uint8 {
  118. fieldValue.Set(reflect.ValueOf(v))
  119. } else {
  120. x := reflect.New(fieldType)
  121. if len(data) > 0 {
  122. err := DefaultJSONHandler.Unmarshal(data, x.Interface())
  123. if err != nil {
  124. session.engine.logger.Error(err)
  125. return err
  126. }
  127. fieldValue.Set(x.Elem())
  128. }
  129. }
  130. } else {
  131. return ErrUnSupportedType
  132. }
  133. case reflect.String:
  134. fieldValue.SetString(string(data))
  135. case reflect.Bool:
  136. v, err := asBool(data)
  137. if err != nil {
  138. return fmt.Errorf("arg %v as bool: %s", key, err.Error())
  139. }
  140. fieldValue.Set(reflect.ValueOf(v))
  141. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  142. sdata := string(data)
  143. var x int64
  144. var err error
  145. // for mysql, when use bit, it returned \x01
  146. if col.SQLType.Name == core.Bit &&
  147. session.engine.dialect.DBType() == core.MYSQL { // !nashtsai! TODO dialect needs to provide conversion interface API
  148. if len(data) == 1 {
  149. x = int64(data[0])
  150. } else {
  151. x = 0
  152. }
  153. } else if strings.HasPrefix(sdata, "0x") {
  154. x, err = strconv.ParseInt(sdata, 16, 64)
  155. } else if strings.HasPrefix(sdata, "0") {
  156. x, err = strconv.ParseInt(sdata, 8, 64)
  157. } else if strings.EqualFold(sdata, "true") {
  158. x = 1
  159. } else if strings.EqualFold(sdata, "false") {
  160. x = 0
  161. } else {
  162. x, err = strconv.ParseInt(sdata, 10, 64)
  163. }
  164. if err != nil {
  165. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  166. }
  167. fieldValue.SetInt(x)
  168. case reflect.Float32, reflect.Float64:
  169. x, err := strconv.ParseFloat(string(data), 64)
  170. if err != nil {
  171. return fmt.Errorf("arg %v as float64: %s", key, err.Error())
  172. }
  173. fieldValue.SetFloat(x)
  174. case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
  175. x, err := strconv.ParseUint(string(data), 10, 64)
  176. if err != nil {
  177. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  178. }
  179. fieldValue.SetUint(x)
  180. //Currently only support Time type
  181. case reflect.Struct:
  182. // !<winxxp>! 增加支持sql.Scanner接口的结构,如sql.NullString
  183. if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
  184. if err := nulVal.Scan(data); err != nil {
  185. return fmt.Errorf("sql.Scan(%v) failed: %s ", data, err.Error())
  186. }
  187. } else {
  188. if fieldType.ConvertibleTo(core.TimeType) {
  189. x, err := session.byte2Time(col, data)
  190. if err != nil {
  191. return err
  192. }
  193. v = x
  194. fieldValue.Set(reflect.ValueOf(v).Convert(fieldType))
  195. } else if session.statement.UseCascade {
  196. table, err := session.engine.autoMapType(*fieldValue)
  197. if err != nil {
  198. return err
  199. }
  200. // TODO: current only support 1 primary key
  201. if len(table.PrimaryKeys) > 1 {
  202. return errors.New("unsupported composited primary key cascade")
  203. }
  204. var pk = make(core.PK, len(table.PrimaryKeys))
  205. rawValueType := table.ColumnType(table.PKColumns()[0].FieldName)
  206. pk[0], err = str2PK(string(data), rawValueType)
  207. if err != nil {
  208. return err
  209. }
  210. if !isPKZero(pk) {
  211. // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
  212. // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
  213. // property to be fetched lazily
  214. structInter := reflect.New(fieldValue.Type())
  215. has, err := session.ID(pk).NoCascade().get(structInter.Interface())
  216. if err != nil {
  217. return err
  218. }
  219. if has {
  220. v = structInter.Elem().Interface()
  221. fieldValue.Set(reflect.ValueOf(v))
  222. } else {
  223. return errors.New("cascade obj is not exist")
  224. }
  225. }
  226. }
  227. }
  228. case reflect.Ptr:
  229. // !nashtsai! TODO merge duplicated codes above
  230. //typeStr := fieldType.String()
  231. switch fieldType.Elem().Kind() {
  232. // case "*string":
  233. case core.StringType.Kind():
  234. x := string(data)
  235. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  236. // case "*bool":
  237. case core.BoolType.Kind():
  238. d := string(data)
  239. v, err := strconv.ParseBool(d)
  240. if err != nil {
  241. return fmt.Errorf("arg %v as bool: %s", key, err.Error())
  242. }
  243. fieldValue.Set(reflect.ValueOf(&v).Convert(fieldType))
  244. // case "*complex64":
  245. case core.Complex64Type.Kind():
  246. var x complex64
  247. if len(data) > 0 {
  248. err := DefaultJSONHandler.Unmarshal(data, &x)
  249. if err != nil {
  250. session.engine.logger.Error(err)
  251. return err
  252. }
  253. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  254. }
  255. // case "*complex128":
  256. case core.Complex128Type.Kind():
  257. var x complex128
  258. if len(data) > 0 {
  259. err := DefaultJSONHandler.Unmarshal(data, &x)
  260. if err != nil {
  261. session.engine.logger.Error(err)
  262. return err
  263. }
  264. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  265. }
  266. // case "*float64":
  267. case core.Float64Type.Kind():
  268. x, err := strconv.ParseFloat(string(data), 64)
  269. if err != nil {
  270. return fmt.Errorf("arg %v as float64: %s", key, err.Error())
  271. }
  272. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  273. // case "*float32":
  274. case core.Float32Type.Kind():
  275. var x float32
  276. x1, err := strconv.ParseFloat(string(data), 32)
  277. if err != nil {
  278. return fmt.Errorf("arg %v as float32: %s", key, err.Error())
  279. }
  280. x = float32(x1)
  281. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  282. // case "*uint64":
  283. case core.Uint64Type.Kind():
  284. var x uint64
  285. x, err := strconv.ParseUint(string(data), 10, 64)
  286. if err != nil {
  287. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  288. }
  289. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  290. // case "*uint":
  291. case core.UintType.Kind():
  292. var x uint
  293. x1, err := strconv.ParseUint(string(data), 10, 64)
  294. if err != nil {
  295. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  296. }
  297. x = uint(x1)
  298. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  299. // case "*uint32":
  300. case core.Uint32Type.Kind():
  301. var x uint32
  302. x1, err := strconv.ParseUint(string(data), 10, 64)
  303. if err != nil {
  304. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  305. }
  306. x = uint32(x1)
  307. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  308. // case "*uint8":
  309. case core.Uint8Type.Kind():
  310. var x uint8
  311. x1, err := strconv.ParseUint(string(data), 10, 64)
  312. if err != nil {
  313. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  314. }
  315. x = uint8(x1)
  316. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  317. // case "*uint16":
  318. case core.Uint16Type.Kind():
  319. var x uint16
  320. x1, err := strconv.ParseUint(string(data), 10, 64)
  321. if err != nil {
  322. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  323. }
  324. x = uint16(x1)
  325. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  326. // case "*int64":
  327. case core.Int64Type.Kind():
  328. sdata := string(data)
  329. var x int64
  330. var err error
  331. // for mysql, when use bit, it returned \x01
  332. if col.SQLType.Name == core.Bit &&
  333. strings.Contains(session.engine.DriverName(), "mysql") {
  334. if len(data) == 1 {
  335. x = int64(data[0])
  336. } else {
  337. x = 0
  338. }
  339. } else if strings.HasPrefix(sdata, "0x") {
  340. x, err = strconv.ParseInt(sdata, 16, 64)
  341. } else if strings.HasPrefix(sdata, "0") {
  342. x, err = strconv.ParseInt(sdata, 8, 64)
  343. } else {
  344. x, err = strconv.ParseInt(sdata, 10, 64)
  345. }
  346. if err != nil {
  347. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  348. }
  349. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  350. // case "*int":
  351. case core.IntType.Kind():
  352. sdata := string(data)
  353. var x int
  354. var x1 int64
  355. var err error
  356. // for mysql, when use bit, it returned \x01
  357. if col.SQLType.Name == core.Bit &&
  358. strings.Contains(session.engine.DriverName(), "mysql") {
  359. if len(data) == 1 {
  360. x = int(data[0])
  361. } else {
  362. x = 0
  363. }
  364. } else if strings.HasPrefix(sdata, "0x") {
  365. x1, err = strconv.ParseInt(sdata, 16, 64)
  366. x = int(x1)
  367. } else if strings.HasPrefix(sdata, "0") {
  368. x1, err = strconv.ParseInt(sdata, 8, 64)
  369. x = int(x1)
  370. } else {
  371. x1, err = strconv.ParseInt(sdata, 10, 64)
  372. x = int(x1)
  373. }
  374. if err != nil {
  375. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  376. }
  377. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  378. // case "*int32":
  379. case core.Int32Type.Kind():
  380. sdata := string(data)
  381. var x int32
  382. var x1 int64
  383. var err error
  384. // for mysql, when use bit, it returned \x01
  385. if col.SQLType.Name == core.Bit &&
  386. session.engine.dialect.DBType() == core.MYSQL {
  387. if len(data) == 1 {
  388. x = int32(data[0])
  389. } else {
  390. x = 0
  391. }
  392. } else if strings.HasPrefix(sdata, "0x") {
  393. x1, err = strconv.ParseInt(sdata, 16, 64)
  394. x = int32(x1)
  395. } else if strings.HasPrefix(sdata, "0") {
  396. x1, err = strconv.ParseInt(sdata, 8, 64)
  397. x = int32(x1)
  398. } else {
  399. x1, err = strconv.ParseInt(sdata, 10, 64)
  400. x = int32(x1)
  401. }
  402. if err != nil {
  403. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  404. }
  405. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  406. // case "*int8":
  407. case core.Int8Type.Kind():
  408. sdata := string(data)
  409. var x int8
  410. var x1 int64
  411. var err error
  412. // for mysql, when use bit, it returned \x01
  413. if col.SQLType.Name == core.Bit &&
  414. strings.Contains(session.engine.DriverName(), "mysql") {
  415. if len(data) == 1 {
  416. x = int8(data[0])
  417. } else {
  418. x = 0
  419. }
  420. } else if strings.HasPrefix(sdata, "0x") {
  421. x1, err = strconv.ParseInt(sdata, 16, 64)
  422. x = int8(x1)
  423. } else if strings.HasPrefix(sdata, "0") {
  424. x1, err = strconv.ParseInt(sdata, 8, 64)
  425. x = int8(x1)
  426. } else {
  427. x1, err = strconv.ParseInt(sdata, 10, 64)
  428. x = int8(x1)
  429. }
  430. if err != nil {
  431. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  432. }
  433. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  434. // case "*int16":
  435. case core.Int16Type.Kind():
  436. sdata := string(data)
  437. var x int16
  438. var x1 int64
  439. var err error
  440. // for mysql, when use bit, it returned \x01
  441. if col.SQLType.Name == core.Bit &&
  442. strings.Contains(session.engine.DriverName(), "mysql") {
  443. if len(data) == 1 {
  444. x = int16(data[0])
  445. } else {
  446. x = 0
  447. }
  448. } else if strings.HasPrefix(sdata, "0x") {
  449. x1, err = strconv.ParseInt(sdata, 16, 64)
  450. x = int16(x1)
  451. } else if strings.HasPrefix(sdata, "0") {
  452. x1, err = strconv.ParseInt(sdata, 8, 64)
  453. x = int16(x1)
  454. } else {
  455. x1, err = strconv.ParseInt(sdata, 10, 64)
  456. x = int16(x1)
  457. }
  458. if err != nil {
  459. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  460. }
  461. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  462. // case "*SomeStruct":
  463. case reflect.Struct:
  464. switch fieldType {
  465. // case "*.time.Time":
  466. case core.PtrTimeType:
  467. x, err := session.byte2Time(col, data)
  468. if err != nil {
  469. return err
  470. }
  471. v = x
  472. fieldValue.Set(reflect.ValueOf(&x))
  473. default:
  474. if session.statement.UseCascade {
  475. structInter := reflect.New(fieldType.Elem())
  476. table, err := session.engine.autoMapType(structInter.Elem())
  477. if err != nil {
  478. return err
  479. }
  480. if len(table.PrimaryKeys) > 1 {
  481. return errors.New("unsupported composited primary key cascade")
  482. }
  483. var pk = make(core.PK, len(table.PrimaryKeys))
  484. rawValueType := table.ColumnType(table.PKColumns()[0].FieldName)
  485. pk[0], err = str2PK(string(data), rawValueType)
  486. if err != nil {
  487. return err
  488. }
  489. if !isPKZero(pk) {
  490. // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
  491. // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
  492. // property to be fetched lazily
  493. has, err := session.ID(pk).NoCascade().get(structInter.Interface())
  494. if err != nil {
  495. return err
  496. }
  497. if has {
  498. v = structInter.Interface()
  499. fieldValue.Set(reflect.ValueOf(v))
  500. } else {
  501. return errors.New("cascade obj is not exist")
  502. }
  503. }
  504. } else {
  505. return fmt.Errorf("unsupported struct type in Scan: %s", fieldValue.Type().String())
  506. }
  507. }
  508. default:
  509. return fmt.Errorf("unsupported type in Scan: %s", fieldValue.Type().String())
  510. }
  511. default:
  512. return fmt.Errorf("unsupported type in Scan: %s", fieldValue.Type().String())
  513. }
  514. return nil
  515. }
  516. // convert a field value of a struct to interface for put into db
  517. func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Value) (interface{}, error) {
  518. if fieldValue.CanAddr() {
  519. if fieldConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok {
  520. data, err := fieldConvert.ToDB()
  521. if err != nil {
  522. return 0, err
  523. }
  524. if col.SQLType.IsBlob() {
  525. return data, nil
  526. }
  527. return string(data), nil
  528. }
  529. }
  530. if fieldConvert, ok := fieldValue.Interface().(core.Conversion); ok {
  531. data, err := fieldConvert.ToDB()
  532. if err != nil {
  533. return 0, err
  534. }
  535. if col.SQLType.IsBlob() {
  536. return data, nil
  537. }
  538. return string(data), nil
  539. }
  540. fieldType := fieldValue.Type()
  541. k := fieldType.Kind()
  542. if k == reflect.Ptr {
  543. if fieldValue.IsNil() {
  544. return nil, nil
  545. } else if !fieldValue.IsValid() {
  546. session.engine.logger.Warn("the field[", col.FieldName, "] is invalid")
  547. return nil, nil
  548. } else {
  549. // !nashtsai! deference pointer type to instance type
  550. fieldValue = fieldValue.Elem()
  551. fieldType = fieldValue.Type()
  552. k = fieldType.Kind()
  553. }
  554. }
  555. switch k {
  556. case reflect.Bool:
  557. return fieldValue.Bool(), nil
  558. case reflect.String:
  559. return fieldValue.String(), nil
  560. case reflect.Struct:
  561. if fieldType.ConvertibleTo(core.TimeType) {
  562. t := fieldValue.Convert(core.TimeType).Interface().(time.Time)
  563. tf := session.engine.formatColTime(col, t)
  564. return tf, nil
  565. } else if fieldType.ConvertibleTo(nullFloatType) {
  566. t := fieldValue.Convert(nullFloatType).Interface().(sql.NullFloat64)
  567. if !t.Valid {
  568. return nil, nil
  569. }
  570. return t.Float64, nil
  571. }
  572. if !col.SQLType.IsJson() {
  573. // !<winxxp>! 增加支持driver.Valuer接口的结构,如sql.NullString
  574. if v, ok := fieldValue.Interface().(driver.Valuer); ok {
  575. return v.Value()
  576. }
  577. fieldTable, err := session.engine.autoMapType(fieldValue)
  578. if err != nil {
  579. return nil, err
  580. }
  581. if len(fieldTable.PrimaryKeys) == 1 {
  582. pkField := reflect.Indirect(fieldValue).FieldByName(fieldTable.PKColumns()[0].FieldName)
  583. return pkField.Interface(), nil
  584. }
  585. return 0, fmt.Errorf("no primary key for col %v", col.Name)
  586. }
  587. if col.SQLType.IsText() {
  588. bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface())
  589. if err != nil {
  590. session.engine.logger.Error(err)
  591. return 0, err
  592. }
  593. return string(bytes), nil
  594. } else if col.SQLType.IsBlob() {
  595. bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface())
  596. if err != nil {
  597. session.engine.logger.Error(err)
  598. return 0, err
  599. }
  600. return bytes, nil
  601. }
  602. return nil, fmt.Errorf("Unsupported type %v", fieldValue.Type())
  603. case reflect.Complex64, reflect.Complex128:
  604. bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface())
  605. if err != nil {
  606. session.engine.logger.Error(err)
  607. return 0, err
  608. }
  609. return string(bytes), nil
  610. case reflect.Array, reflect.Slice, reflect.Map:
  611. if !fieldValue.IsValid() {
  612. return fieldValue.Interface(), nil
  613. }
  614. if col.SQLType.IsText() {
  615. bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface())
  616. if err != nil {
  617. session.engine.logger.Error(err)
  618. return 0, err
  619. }
  620. return string(bytes), nil
  621. } else if col.SQLType.IsBlob() {
  622. var bytes []byte
  623. var err error
  624. if (k == reflect.Slice) &&
  625. (fieldValue.Type().Elem().Kind() == reflect.Uint8) {
  626. bytes = fieldValue.Bytes()
  627. } else {
  628. bytes, err = DefaultJSONHandler.Marshal(fieldValue.Interface())
  629. if err != nil {
  630. session.engine.logger.Error(err)
  631. return 0, err
  632. }
  633. }
  634. return bytes, nil
  635. }
  636. return nil, ErrUnSupportedType
  637. case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
  638. return int64(fieldValue.Uint()), nil
  639. default:
  640. return fieldValue.Interface(), nil
  641. }
  642. }