sessionplus.go 33 KB

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