sessionplus.go 26 KB

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