sessionplus.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. // Copyright 2015 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. "encoding/json"
  8. "errors"
  9. // "fmt"
  10. "reflect"
  11. "regexp"
  12. "strings"
  13. "time"
  14. "github.com/Chronokeeper/anyxml"
  15. "github.com/xormplus/core"
  16. )
  17. type ResultBean struct {
  18. Has bool
  19. Result interface{}
  20. Error error
  21. }
  22. func (resultBean ResultBean) Json() (bool, string, error) {
  23. if resultBean.Error != nil {
  24. return resultBean.Has, "", resultBean.Error
  25. }
  26. if !resultBean.Has {
  27. return resultBean.Has, "", nil
  28. }
  29. result, err := JSONString(resultBean.Result, true)
  30. return resultBean.Has, result, err
  31. }
  32. func (session *Session) GetFirst(bean interface{}) ResultBean {
  33. has, err := session.Get(bean)
  34. r := ResultBean{Has: has, Result: bean, Error: err}
  35. return r
  36. }
  37. func (resultBean ResultBean) Xml() (bool, string, error) {
  38. if resultBean.Error != nil {
  39. return false, "", resultBean.Error
  40. }
  41. if !resultBean.Has {
  42. return resultBean.Has, "", nil
  43. }
  44. has, result, err := resultBean.Json()
  45. if err != nil {
  46. return false, "", err
  47. }
  48. if !has {
  49. return has, "", nil
  50. }
  51. var anydata = []byte(result)
  52. var i interface{}
  53. err = json.Unmarshal(anydata, &i)
  54. if err != nil {
  55. return false, "", err
  56. }
  57. resultByte, err := anyxml.Xml(i)
  58. if err != nil {
  59. return false, "", err
  60. }
  61. return resultBean.Has, string(resultByte), err
  62. }
  63. func (resultBean ResultBean) XmlIndent(prefix string, indent string, recordTag string) (bool, string, error) {
  64. if resultBean.Error != nil {
  65. return false, "", resultBean.Error
  66. }
  67. if !resultBean.Has {
  68. return resultBean.Has, "", nil
  69. }
  70. has, result, err := resultBean.Json()
  71. if err != nil {
  72. return false, "", err
  73. }
  74. if !has {
  75. return has, "", nil
  76. }
  77. var anydata = []byte(result)
  78. var i interface{}
  79. err = json.Unmarshal(anydata, &i)
  80. if err != nil {
  81. return false, "", err
  82. }
  83. resultByte, err := anyxml.XmlIndent(i, prefix, indent, recordTag)
  84. if err != nil {
  85. return false, "", err
  86. }
  87. return resultBean.Has, string(resultByte), err
  88. }
  89. type ResultMap struct {
  90. Result []map[string]interface{}
  91. Error error
  92. }
  93. func (resultMap ResultMap) Json() (string, error) {
  94. if resultMap.Error != nil {
  95. return "", resultMap.Error
  96. }
  97. return JSONString(resultMap.Result, true)
  98. }
  99. func (resultMap ResultMap) Xml() (string, error) {
  100. if resultMap.Error != nil {
  101. return "", resultMap.Error
  102. }
  103. results, err := anyxml.Xml(resultMap.Result)
  104. if err != nil {
  105. return "", err
  106. }
  107. return string(results), nil
  108. }
  109. func (resultMap ResultMap) XmlIndent(prefix string, indent string, recordTag string) (string, error) {
  110. if resultMap.Error != nil {
  111. return "", resultMap.Error
  112. }
  113. results, err := anyxml.XmlIndent(resultMap.Result, prefix, indent, recordTag)
  114. if err != nil {
  115. return "", err
  116. }
  117. return string(results), nil
  118. }
  119. type ResultStructs struct {
  120. Result interface{}
  121. Error error
  122. }
  123. func (resultStructs ResultStructs) Json() (string, error) {
  124. if resultStructs.Error != nil {
  125. return "", resultStructs.Error
  126. }
  127. return JSONString(resultStructs.Result, true)
  128. }
  129. func (resultStructs ResultStructs) Xml() (string, error) {
  130. if resultStructs.Error != nil {
  131. return "", resultStructs.Error
  132. }
  133. result, err := resultStructs.Json()
  134. if err != nil {
  135. return "", err
  136. }
  137. var anydata = []byte(result)
  138. var i interface{}
  139. err = json.Unmarshal(anydata, &i)
  140. if err != nil {
  141. return "", err
  142. }
  143. resultByte, err := anyxml.Xml(i)
  144. if err != nil {
  145. return "", err
  146. }
  147. return string(resultByte), nil
  148. }
  149. func (resultStructs ResultStructs) XmlIndent(prefix string, indent string, recordTag string) (string, error) {
  150. if resultStructs.Error != nil {
  151. return "", resultStructs.Error
  152. }
  153. result, err := resultStructs.Json()
  154. if err != nil {
  155. return "", err
  156. }
  157. var anydata = []byte(result)
  158. var i interface{}
  159. err = json.Unmarshal(anydata, &i)
  160. if err != nil {
  161. return "", err
  162. }
  163. resultByte, err := anyxml.XmlIndent(i, prefix, indent, recordTag)
  164. if err != nil {
  165. return "", err
  166. }
  167. return string(resultByte), nil
  168. }
  169. func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) ResultStructs {
  170. err := session.find(rowsSlicePtr, condiBean...)
  171. r := ResultStructs{Result: rowsSlicePtr, Error: err}
  172. return r
  173. }
  174. // Exec a raw sql and return records as []map[string]interface{}
  175. func (session *Session) Query() ResultMap {
  176. sql := session.Statement.RawSQL
  177. params := session.Statement.RawParams
  178. result, err := session.queryAll(sql, params...)
  179. r := ResultMap{Result: result, Error: err}
  180. return r
  181. }
  182. // Exec a raw sql and return records as []map[string]interface{}
  183. func (session *Session) QueryWithDateFormat(dateFormat string) ResultMap {
  184. sql := session.Statement.RawSQL
  185. params := session.Statement.RawParams
  186. result, err := session.queryAllWithDateFormat(dateFormat, sql, params...)
  187. r := ResultMap{Result: result, Error: err}
  188. return r
  189. }
  190. // Exec a raw sql and return records as []map[string]interface{}
  191. func (session *Session) QueryByParamMap() ResultMap {
  192. sql := session.Statement.RawSQL
  193. params := session.Statement.RawParams
  194. result, err := session.queryAllByMap(sql, params[0])
  195. r := ResultMap{Result: result, Error: err}
  196. return r
  197. }
  198. func (session *Session) QueryByParamMapWithDateFormat(dateFormat string) ResultMap {
  199. sql := session.Statement.RawSQL
  200. params := session.Statement.RawParams
  201. results, err := session.queryAllByMapWithDateFormat(dateFormat, sql, params[0])
  202. r := ResultMap{Result: results, Error: err}
  203. return r
  204. }
  205. // =============================
  206. // for Object
  207. // =============================
  208. func (session *Session) queryAll(sqlStr string, paramStr ...interface{}) (resultsSlice []map[string]interface{}, err error) {
  209. session.queryPreprocess(&sqlStr, paramStr...)
  210. if session.IsAutoCommit {
  211. return query3(session.DB(), sqlStr, paramStr...)
  212. }
  213. return txQuery3(session.Tx, sqlStr, paramStr...)
  214. }
  215. func (session *Session) queryAllByMap(sqlStr string, paramMap interface{}) (resultsSlice []map[string]interface{}, err error) {
  216. sqlStr1, param, _ := core.MapToSlice(sqlStr, paramMap)
  217. session.queryPreprocess(&sqlStr1, param...)
  218. if session.IsAutoCommit {
  219. return query3(session.DB(), sqlStr1, param...)
  220. }
  221. return txQuery3(session.Tx, sqlStr1, param...)
  222. }
  223. func (session *Session) queryAllByMapWithDateFormat(dateFormat string, sqlStr string, paramMap interface{}) (resultsSlice []map[string]interface{}, err error) {
  224. sqlStr1, param, _ := core.MapToSlice(sqlStr, paramMap)
  225. session.queryPreprocess(&sqlStr1, param...)
  226. if session.IsAutoCommit {
  227. return query3WithDateFormat(session.DB(), dateFormat, sqlStr1, param...)
  228. }
  229. return txQuery3WithDateFormat(session.Tx, dateFormat, sqlStr1, param...)
  230. }
  231. func (session *Session) queryAllWithDateFormat(dateFormat string, sqlStr string, paramStr ...interface{}) (resultsSlice []map[string]interface{}, err error) {
  232. session.queryPreprocess(&sqlStr, paramStr...)
  233. if session.IsAutoCommit {
  234. return query3WithDateFormat(session.DB(), dateFormat, sqlStr, paramStr...)
  235. }
  236. return txQuery3WithDateFormat(session.Tx, dateFormat, sqlStr, paramStr...)
  237. }
  238. func (session *Session) queryAllToJsonString(sql string, paramStr ...interface{}) (string, error) {
  239. results, err := session.queryAll(sql, paramStr...)
  240. if err != nil {
  241. return "", err
  242. }
  243. return JSONString(results, true)
  244. }
  245. func (session *Session) queryAllToXmlString(sql string, paramStr ...interface{}) (string, error) {
  246. resultMap, err := session.queryAll(sql, paramStr...)
  247. if err != nil {
  248. return "", err
  249. }
  250. results, err := anyxml.Xml(resultMap)
  251. if err != nil {
  252. return "", err
  253. }
  254. return string(results), nil
  255. }
  256. func (session *Session) queryAllToXmlIndentString(sql string, prefix string, indent string, paramStr ...interface{}) (string, error) {
  257. resultSlice, err := session.queryAll(sql, paramStr...)
  258. if err != nil {
  259. return "", err
  260. }
  261. results, err := anyxml.XmlIndent(resultSlice, prefix, indent, "result")
  262. if err != nil {
  263. return "", err
  264. }
  265. return string(results), nil
  266. }
  267. func (session *Session) queryAllToXmlStringWithDateFormat(dateFormat string, sql string, paramStr ...interface{}) (string, error) {
  268. resultSlice, err := session.queryAll(sql, paramStr...)
  269. if err != nil {
  270. return "", err
  271. }
  272. results, err := anyxml.XmlWithDateFormat(dateFormat, resultSlice)
  273. if err != nil {
  274. return "", err
  275. }
  276. return string(results), nil
  277. }
  278. func (session *Session) queryAllToXmlIndentStringWithDateFormat(dateFormat string, sql string, prefix string, indent string, paramStr ...interface{}) (string, error) {
  279. resultSlice, err := session.queryAll(sql, paramStr...)
  280. if err != nil {
  281. return "", err
  282. }
  283. results, err := anyxml.XmlIndentWithDateFormat(dateFormat, resultSlice, prefix, indent, "results")
  284. if err != nil {
  285. return "", err
  286. }
  287. return string(results), nil
  288. }
  289. func (session *Session) queryAllByMapToJsonString(sql string, paramMap interface{}) (string, error) {
  290. results, err := session.queryAllByMap(sql, paramMap)
  291. if err != nil {
  292. return "", err
  293. }
  294. return JSONString(results, true)
  295. }
  296. func (session *Session) queryAllByMapToJsonStringWithDateFormat(dateFormat string, sql string, paramMap interface{}) (string, error) {
  297. results, err := session.queryAllByMapWithDateFormat(dateFormat, sql, paramMap)
  298. if err != nil {
  299. return "", err
  300. }
  301. return JSONString(results, true)
  302. }
  303. func (session *Session) queryAllToJsonStringWithDateFormat(dateFormat string, sql string, paramStr ...interface{}) (string, error) {
  304. results, err := session.queryAllWithDateFormat(dateFormat, sql, paramStr...)
  305. if err != nil {
  306. return "", err
  307. }
  308. return JSONString(results, true)
  309. }
  310. func (session *Session) row2BeanWithDateFormat(dateFormat string, rows *core.Rows, fields []string, fieldsCount int, bean interface{}) error {
  311. dataStruct := rValue(bean)
  312. if dataStruct.Kind() != reflect.Struct {
  313. return errors.New("Expected a pointer to a struct")
  314. }
  315. table := session.Engine.autoMapType(dataStruct)
  316. return session._row2BeanWithDateFormat(dateFormat, rows, fields, fieldsCount, bean, &dataStruct, table)
  317. }
  318. func (session *Session) _row2BeanWithDateFormat(dateFormat string, rows *core.Rows, fields []string, fieldsCount int, bean interface{}, dataStruct *reflect.Value, table *core.Table) error {
  319. scanResults := make([]interface{}, fieldsCount)
  320. for i := 0; i < len(fields); i++ {
  321. var cell interface{}
  322. scanResults[i] = &cell
  323. }
  324. if err := rows.Scan(scanResults...); err != nil {
  325. return err
  326. }
  327. if b, hasBeforeSet := bean.(BeforeSetProcessor); hasBeforeSet {
  328. for ii, key := range fields {
  329. b.BeforeSet(key, Cell(scanResults[ii].(*interface{})))
  330. }
  331. }
  332. defer func() {
  333. if b, hasAfterSet := bean.(AfterSetProcessor); hasAfterSet {
  334. for ii, key := range fields {
  335. b.AfterSet(key, Cell(scanResults[ii].(*interface{})))
  336. }
  337. }
  338. }()
  339. var tempMap = make(map[string]int)
  340. for ii, key := range fields {
  341. var idx int
  342. var ok bool
  343. if idx, ok = tempMap[strings.ToLower(key)]; !ok {
  344. idx = 0
  345. } else {
  346. idx = idx + 1
  347. }
  348. tempMap[strings.ToLower(key)] = idx
  349. if fieldValue := session.getField(dataStruct, key, table, idx); fieldValue != nil {
  350. rawValue := reflect.Indirect(reflect.ValueOf(scanResults[ii]))
  351. //if row is null then ignore
  352. if rawValue.Interface() == nil {
  353. continue
  354. }
  355. if fieldValue.CanAddr() {
  356. if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok {
  357. if data, err := value2Bytes(&rawValue); err == nil {
  358. structConvert.FromDB(data)
  359. } else {
  360. session.Engine.LogError(err)
  361. }
  362. continue
  363. }
  364. }
  365. if _, ok := fieldValue.Interface().(core.Conversion); ok {
  366. if data, err := value2Bytes(&rawValue); err == nil {
  367. if fieldValue.Kind() == reflect.Ptr && fieldValue.IsNil() {
  368. fieldValue.Set(reflect.New(fieldValue.Type().Elem()))
  369. }
  370. fieldValue.Interface().(core.Conversion).FromDB(data)
  371. } else {
  372. session.Engine.LogError(err)
  373. }
  374. continue
  375. }
  376. rawValueType := reflect.TypeOf(rawValue.Interface())
  377. vv := reflect.ValueOf(rawValue.Interface())
  378. fieldType := fieldValue.Type()
  379. hasAssigned := false
  380. switch fieldType.Kind() {
  381. case reflect.Complex64, reflect.Complex128:
  382. if rawValueType.Kind() == reflect.String {
  383. hasAssigned = true
  384. x := reflect.New(fieldType)
  385. err := json.Unmarshal([]byte(vv.String()), x.Interface())
  386. if err != nil {
  387. session.Engine.LogError(err)
  388. return err
  389. }
  390. fieldValue.Set(x.Elem())
  391. } else if rawValueType.Kind() == reflect.Slice {
  392. hasAssigned = true
  393. x := reflect.New(fieldType)
  394. err := json.Unmarshal(vv.Bytes(), x.Interface())
  395. if err != nil {
  396. session.Engine.LogError(err)
  397. return err
  398. }
  399. fieldValue.Set(x.Elem())
  400. }
  401. case reflect.Slice, reflect.Array:
  402. switch rawValueType.Kind() {
  403. case reflect.Slice, reflect.Array:
  404. switch rawValueType.Elem().Kind() {
  405. case reflect.Uint8:
  406. if fieldType.Elem().Kind() == reflect.Uint8 {
  407. hasAssigned = true
  408. fieldValue.Set(vv)
  409. }
  410. }
  411. }
  412. case reflect.String:
  413. if rawValueType.Kind() == reflect.String {
  414. hasAssigned = true
  415. fieldValue.SetString(vv.String())
  416. }
  417. case reflect.Bool:
  418. if rawValueType.Kind() == reflect.Bool {
  419. hasAssigned = true
  420. fieldValue.SetBool(vv.Bool())
  421. }
  422. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  423. switch rawValueType.Kind() {
  424. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  425. hasAssigned = true
  426. fieldValue.SetInt(vv.Int())
  427. }
  428. case reflect.Float32, reflect.Float64:
  429. switch rawValueType.Kind() {
  430. case reflect.Float32, reflect.Float64:
  431. hasAssigned = true
  432. fieldValue.SetFloat(vv.Float())
  433. }
  434. case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
  435. switch rawValueType.Kind() {
  436. case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
  437. hasAssigned = true
  438. fieldValue.SetUint(vv.Uint())
  439. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  440. hasAssigned = true
  441. fieldValue.SetUint(uint64(vv.Int()))
  442. }
  443. case reflect.Struct:
  444. col := table.GetColumn(key)
  445. if fieldType.ConvertibleTo(core.TimeType) {
  446. if rawValueType == core.TimeType {
  447. hasAssigned = true
  448. t := vv.Convert(core.TimeType).Interface().(time.Time)
  449. z, _ := t.Zone()
  450. if len(z) == 0 || t.Year() == 0 { // !nashtsai! HACK tmp work around for lib/pq doesn't properly time with location
  451. session.Engine.LogDebugf("empty zone key[%v] : %v | zone: %v | location: %+v\n", key, t, z, *t.Location())
  452. t = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(),
  453. t.Minute(), t.Second(), t.Nanosecond(), time.Local)
  454. }
  455. // !nashtsai! convert to engine location
  456. t = t.In(session.Engine.TZLocation)
  457. // dateFormat to string
  458. loc, _ := time.LoadLocation("Local") //重要:获取时区 rawValue.Interface().(time.Time).Format(dateFormat)
  459. t, _ = time.ParseInLocation(dateFormat, t.Format(dateFormat), loc)
  460. // fieldValue.Set(reflect.ValueOf(t).Convert(core.StringType))
  461. fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
  462. // t = fieldValue.Interface().(time.Time)
  463. // z, _ = t.Zone()
  464. // session.Engine.LogDebug("fieldValue key[%v]: %v | zone: %v | location: %+v\n", key, t, z, *t.Location())
  465. } else if rawValueType == core.IntType || rawValueType == core.Int64Type ||
  466. rawValueType == core.Int32Type {
  467. hasAssigned = true
  468. t := time.Unix(vv.Int(), 0).In(session.Engine.TZLocation)
  469. vv = reflect.ValueOf(t)
  470. fieldValue.Set(vv)
  471. }
  472. } else if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
  473. // !<winxxp>! 增加支持sql.Scanner接口的结构,如sql.NullString
  474. hasAssigned = true
  475. if err := nulVal.Scan(vv.Interface()); err != nil {
  476. //fmt.Println("sql.Sanner error:", err.Error())
  477. session.Engine.LogError("sql.Sanner error:", err.Error())
  478. hasAssigned = false
  479. }
  480. } else if col.SQLType.IsJson() {
  481. if rawValueType.Kind() == reflect.String {
  482. hasAssigned = true
  483. x := reflect.New(fieldType)
  484. err := json.Unmarshal([]byte(vv.String()), x.Interface())
  485. if err != nil {
  486. session.Engine.LogError(err)
  487. return err
  488. }
  489. fieldValue.Set(x.Elem())
  490. } else if rawValueType.Kind() == reflect.Slice {
  491. hasAssigned = true
  492. x := reflect.New(fieldType)
  493. err := json.Unmarshal(vv.Bytes(), x.Interface())
  494. if err != nil {
  495. session.Engine.LogError(err)
  496. return err
  497. }
  498. fieldValue.Set(x.Elem())
  499. }
  500. } else if session.Statement.UseCascade {
  501. table := session.Engine.autoMapType(*fieldValue)
  502. if table != nil {
  503. if len(table.PrimaryKeys) != 1 {
  504. panic("unsupported non or composited primary key cascade")
  505. }
  506. var pk = make(core.PK, len(table.PrimaryKeys))
  507. switch rawValueType.Kind() {
  508. case reflect.Int64:
  509. pk[0] = vv.Int()
  510. case reflect.Int:
  511. pk[0] = int(vv.Int())
  512. case reflect.Int32:
  513. pk[0] = int32(vv.Int())
  514. case reflect.Int16:
  515. pk[0] = int16(vv.Int())
  516. case reflect.Int8:
  517. pk[0] = int8(vv.Int())
  518. case reflect.Uint64:
  519. pk[0] = vv.Uint()
  520. case reflect.Uint:
  521. pk[0] = uint(vv.Uint())
  522. case reflect.Uint32:
  523. pk[0] = uint32(vv.Uint())
  524. case reflect.Uint16:
  525. pk[0] = uint16(vv.Uint())
  526. case reflect.Uint8:
  527. pk[0] = uint8(vv.Uint())
  528. case reflect.String:
  529. pk[0] = vv.String()
  530. default:
  531. panic("unsupported primary key type cascade")
  532. }
  533. if !isPKZero(pk) {
  534. // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
  535. // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
  536. // property to be fetched lazily
  537. structInter := reflect.New(fieldValue.Type())
  538. newsession := session.Engine.NewSession()
  539. defer newsession.Close()
  540. has, err := newsession.Id(pk).NoCascade().Get(structInter.Interface())
  541. if err != nil {
  542. return err
  543. }
  544. if has {
  545. v := structInter.Elem().Interface()
  546. fieldValue.Set(reflect.ValueOf(v))
  547. } else {
  548. return errors.New("cascade obj is not exist!")
  549. }
  550. }
  551. } else {
  552. session.Engine.LogError("unsupported struct type in Scan: ", fieldValue.Type().String())
  553. }
  554. }
  555. case reflect.Ptr:
  556. // !nashtsai! TODO merge duplicated codes above
  557. //typeStr := fieldType.String()
  558. switch fieldType {
  559. // following types case matching ptr's native type, therefore assign ptr directly
  560. case core.PtrStringType:
  561. if rawValueType.Kind() == reflect.String {
  562. x := vv.String()
  563. hasAssigned = true
  564. fieldValue.Set(reflect.ValueOf(&x))
  565. }
  566. case core.PtrBoolType:
  567. if rawValueType.Kind() == reflect.Bool {
  568. x := vv.Bool()
  569. hasAssigned = true
  570. fieldValue.Set(reflect.ValueOf(&x))
  571. }
  572. case core.PtrTimeType:
  573. if rawValueType == core.PtrTimeType {
  574. hasAssigned = true
  575. var x time.Time = rawValue.Interface().(time.Time)
  576. fieldValue.Set(reflect.ValueOf(&x))
  577. }
  578. case core.PtrFloat64Type:
  579. if rawValueType.Kind() == reflect.Float64 {
  580. x := vv.Float()
  581. hasAssigned = true
  582. fieldValue.Set(reflect.ValueOf(&x))
  583. }
  584. case core.PtrUint64Type:
  585. if rawValueType.Kind() == reflect.Int64 {
  586. var x uint64 = uint64(vv.Int())
  587. hasAssigned = true
  588. fieldValue.Set(reflect.ValueOf(&x))
  589. }
  590. case core.PtrInt64Type:
  591. if rawValueType.Kind() == reflect.Int64 {
  592. x := vv.Int()
  593. hasAssigned = true
  594. fieldValue.Set(reflect.ValueOf(&x))
  595. }
  596. case core.PtrFloat32Type:
  597. if rawValueType.Kind() == reflect.Float64 {
  598. var x float32 = float32(vv.Float())
  599. hasAssigned = true
  600. fieldValue.Set(reflect.ValueOf(&x))
  601. }
  602. case core.PtrIntType:
  603. if rawValueType.Kind() == reflect.Int64 {
  604. var x int = int(vv.Int())
  605. hasAssigned = true
  606. fieldValue.Set(reflect.ValueOf(&x))
  607. }
  608. case core.PtrInt32Type:
  609. if rawValueType.Kind() == reflect.Int64 {
  610. var x int32 = int32(vv.Int())
  611. hasAssigned = true
  612. fieldValue.Set(reflect.ValueOf(&x))
  613. }
  614. case core.PtrInt8Type:
  615. if rawValueType.Kind() == reflect.Int64 {
  616. var x int8 = int8(vv.Int())
  617. hasAssigned = true
  618. fieldValue.Set(reflect.ValueOf(&x))
  619. }
  620. case core.PtrInt16Type:
  621. if rawValueType.Kind() == reflect.Int64 {
  622. var x int16 = int16(vv.Int())
  623. hasAssigned = true
  624. fieldValue.Set(reflect.ValueOf(&x))
  625. }
  626. case core.PtrUintType:
  627. if rawValueType.Kind() == reflect.Int64 {
  628. var x uint = uint(vv.Int())
  629. hasAssigned = true
  630. fieldValue.Set(reflect.ValueOf(&x))
  631. }
  632. case core.PtrUint32Type:
  633. if rawValueType.Kind() == reflect.Int64 {
  634. var x uint32 = uint32(vv.Int())
  635. hasAssigned = true
  636. fieldValue.Set(reflect.ValueOf(&x))
  637. }
  638. case core.Uint8Type:
  639. if rawValueType.Kind() == reflect.Int64 {
  640. var x uint8 = uint8(vv.Int())
  641. hasAssigned = true
  642. fieldValue.Set(reflect.ValueOf(&x))
  643. }
  644. case core.Uint16Type:
  645. if rawValueType.Kind() == reflect.Int64 {
  646. var x uint16 = uint16(vv.Int())
  647. hasAssigned = true
  648. fieldValue.Set(reflect.ValueOf(&x))
  649. }
  650. case core.Complex64Type:
  651. var x complex64
  652. err := json.Unmarshal([]byte(vv.String()), &x)
  653. if err != nil {
  654. session.Engine.LogError(err)
  655. } else {
  656. fieldValue.Set(reflect.ValueOf(&x))
  657. }
  658. hasAssigned = true
  659. case core.Complex128Type:
  660. var x complex128
  661. err := json.Unmarshal([]byte(vv.String()), &x)
  662. if err != nil {
  663. session.Engine.LogError(err)
  664. } else {
  665. fieldValue.Set(reflect.ValueOf(&x))
  666. }
  667. hasAssigned = true
  668. } // switch fieldType
  669. // default:
  670. // session.Engine.LogError("unsupported type in Scan: ", reflect.TypeOf(v).String())
  671. } // switch fieldType.Kind()
  672. // !nashtsai! for value can't be assigned directly fallback to convert to []byte then back to value
  673. if !hasAssigned {
  674. data, err := value2Bytes(&rawValue)
  675. if err == nil {
  676. session.bytes2Value(table.GetColumn(key), fieldValue, data)
  677. } else {
  678. session.Engine.LogError(err.Error())
  679. }
  680. }
  681. }
  682. }
  683. return nil
  684. }
  685. func (session *Session) queryPreprocessByMap(sqlStr *string, paramMap interface{}) {
  686. re := regexp.MustCompile(`[?](\w+)`)
  687. query := *sqlStr
  688. names := make(map[string]int)
  689. var i int
  690. query = re.ReplaceAllStringFunc(query, func(src string) string {
  691. names[src[1:]] = i
  692. i += 1
  693. return "?"
  694. })
  695. for _, filter := range session.Engine.dialect.Filters() {
  696. query = filter.Do(query, session.Engine.dialect, session.Statement.RefTable)
  697. }
  698. *sqlStr = query
  699. session.Engine.logSQL(*sqlStr, paramMap)
  700. }