sessionplus.go 30 KB

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