sessionplus.go 19 KB

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