session.go 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575
  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. "database/sql/driver"
  8. "encoding/json"
  9. "errors"
  10. "fmt"
  11. "hash/crc32"
  12. "reflect"
  13. "strconv"
  14. "strings"
  15. "time"
  16. "github.com/xormplus/core"
  17. )
  18. // Session keep a pointer to sql.DB and provides all execution of all
  19. // kind of database operations.
  20. type Session struct {
  21. db *core.DB
  22. Engine *Engine
  23. Tx *core.Tx
  24. Statement Statement
  25. currentTransaction *Transaction
  26. IsAutoCommit bool
  27. IsCommitedOrRollbacked bool
  28. IsSqlFunc bool
  29. TransType string
  30. IsAutoClose bool
  31. // Automatically reset the statement after operations that execute a SQL
  32. // query such as Count(), Find(), Get(), ...
  33. AutoResetStatement bool
  34. // !nashtsai! storing these beans due to yet committed tx
  35. afterInsertBeans map[interface{}]*[]func(interface{})
  36. afterUpdateBeans map[interface{}]*[]func(interface{})
  37. afterDeleteBeans map[interface{}]*[]func(interface{})
  38. // --
  39. beforeClosures []func(interface{})
  40. afterClosures []func(interface{})
  41. prepareStmt bool
  42. stmtCache map[uint32]*core.Stmt //key: hash.Hash32 of (queryStr, len(queryStr))
  43. cascadeDeep int
  44. // !evalphobia! stored the last executed query on this session
  45. //beforeSQLExec func(string, ...interface{})
  46. lastSQL string
  47. lastSQLArgs []interface{}
  48. rollbackSavePointID string
  49. }
  50. // Clone copy all the session's content and return a new session.
  51. func (session *Session) Clone() *Session {
  52. var sess = *session
  53. return &sess
  54. }
  55. // Init reset the session as the init status.
  56. func (session *Session) Init() {
  57. session.Statement.Init()
  58. session.Statement.Engine = session.Engine
  59. session.IsAutoCommit = true
  60. session.IsCommitedOrRollbacked = false
  61. session.IsAutoClose = false
  62. session.IsSqlFunc = false
  63. session.AutoResetStatement = true
  64. session.prepareStmt = false
  65. // !nashtsai! is lazy init better?
  66. session.afterInsertBeans = make(map[interface{}]*[]func(interface{}), 0)
  67. session.afterUpdateBeans = make(map[interface{}]*[]func(interface{}), 0)
  68. session.afterDeleteBeans = make(map[interface{}]*[]func(interface{}), 0)
  69. session.beforeClosures = make([]func(interface{}), 0)
  70. session.afterClosures = make([]func(interface{}), 0)
  71. session.lastSQL = ""
  72. session.lastSQLArgs = []interface{}{}
  73. }
  74. // Close release the connection from pool
  75. func (session *Session) Close() {
  76. for _, v := range session.stmtCache {
  77. v.Close()
  78. }
  79. if session.db != nil {
  80. // When Close be called, if session is a transaction and do not call
  81. // Commit or Rollback, then call Rollback.
  82. if session.Tx != nil && !session.IsCommitedOrRollbacked {
  83. session.rollback()
  84. }
  85. session.Tx = nil
  86. session.stmtCache = nil
  87. session.Init()
  88. session.db = nil
  89. }
  90. }
  91. func (session *Session) resetStatement() {
  92. if session.AutoResetStatement {
  93. session.Statement.Init()
  94. }
  95. session.IsSqlFunc = false
  96. }
  97. // Prepare set a flag to session that should be prepare statment before execute query
  98. func (session *Session) Prepare() *Session {
  99. session.prepareStmt = true
  100. return session
  101. }
  102. // Before Apply before Processor, affected bean is passed to closure arg
  103. func (session *Session) Before(closures func(interface{})) *Session {
  104. if closures != nil {
  105. session.beforeClosures = append(session.beforeClosures, closures)
  106. }
  107. return session
  108. }
  109. // After Apply after Processor, affected bean is passed to closure arg
  110. func (session *Session) After(closures func(interface{})) *Session {
  111. if closures != nil {
  112. session.afterClosures = append(session.afterClosures, closures)
  113. }
  114. return session
  115. }
  116. // Table can input a string or pointer to struct for special a table to operate.
  117. func (session *Session) Table(tableNameOrBean interface{}) *Session {
  118. session.Statement.Table(tableNameOrBean)
  119. return session
  120. }
  121. // Alias set the table alias
  122. func (session *Session) Alias(alias string) *Session {
  123. session.Statement.Alias(alias)
  124. return session
  125. }
  126. // Incr provides a query string like "count = count + 1"
  127. func (session *Session) Incr(column string, arg ...interface{}) *Session {
  128. session.Statement.Incr(column, arg...)
  129. return session
  130. }
  131. // Decr provides a query string like "count = count - 1"
  132. func (session *Session) Decr(column string, arg ...interface{}) *Session {
  133. session.Statement.Decr(column, arg...)
  134. return session
  135. }
  136. // SetExpr provides a query string like "column = {expression}"
  137. func (session *Session) SetExpr(column string, expression string) *Session {
  138. session.Statement.SetExpr(column, expression)
  139. return session
  140. }
  141. // Select provides some columns to special
  142. func (session *Session) Select(str string) *Session {
  143. session.Statement.Select(str)
  144. return session
  145. }
  146. // Cols provides some columns to special
  147. func (session *Session) Cols(columns ...string) *Session {
  148. session.Statement.Cols(columns...)
  149. return session
  150. }
  151. // AllCols ask all columns
  152. func (session *Session) AllCols() *Session {
  153. session.Statement.AllCols()
  154. return session
  155. }
  156. // MustCols specify some columns must use even if they are empty
  157. func (session *Session) MustCols(columns ...string) *Session {
  158. session.Statement.MustCols(columns...)
  159. return session
  160. }
  161. // NoCascade indicate that no cascade load child object
  162. func (session *Session) NoCascade() *Session {
  163. session.Statement.UseCascade = false
  164. return session
  165. }
  166. // UseBool automatically retrieve condition according struct, but
  167. // if struct has bool field, it will ignore them. So use UseBool
  168. // to tell system to do not ignore them.
  169. // If no parameters, it will use all the bool field of struct, or
  170. // it will use parameters's columns
  171. func (session *Session) UseBool(columns ...string) *Session {
  172. session.Statement.UseBool(columns...)
  173. return session
  174. }
  175. // Distinct use for distinct columns. Caution: when you are using cache,
  176. // distinct will not be cached because cache system need id,
  177. // but distinct will not provide id
  178. func (session *Session) Distinct(columns ...string) *Session {
  179. session.Statement.Distinct(columns...)
  180. return session
  181. }
  182. // ForUpdate Set Read/Write locking for UPDATE
  183. func (session *Session) ForUpdate() *Session {
  184. session.Statement.IsForUpdate = true
  185. return session
  186. }
  187. // Omit Only not use the parameters as select or update columns
  188. func (session *Session) Omit(columns ...string) *Session {
  189. session.Statement.Omit(columns...)
  190. return session
  191. }
  192. // Nullable Set null when column is zero-value and nullable for update
  193. func (session *Session) Nullable(columns ...string) *Session {
  194. session.Statement.Nullable(columns...)
  195. return session
  196. }
  197. // NoAutoTime means do not automatically give created field and updated field
  198. // the current time on the current session temporarily
  199. func (session *Session) NoAutoTime() *Session {
  200. session.Statement.UseAutoTime = false
  201. return session
  202. }
  203. // NoAutoCondition disable generate SQL condition from beans
  204. func (session *Session) NoAutoCondition(no ...bool) *Session {
  205. session.Statement.NoAutoCondition(no...)
  206. return session
  207. }
  208. // Limit provide limit and offset query condition
  209. func (session *Session) Limit(limit int, start ...int) *Session {
  210. session.Statement.Limit(limit, start...)
  211. return session
  212. }
  213. // OrderBy provide order by query condition, the input parameter is the content
  214. // after order by on a sql statement.
  215. func (session *Session) OrderBy(order string) *Session {
  216. session.Statement.OrderBy(order)
  217. return session
  218. }
  219. // Desc provide desc order by query condition, the input parameters are columns.
  220. func (session *Session) Desc(colNames ...string) *Session {
  221. session.Statement.Desc(colNames...)
  222. return session
  223. }
  224. // Asc provide asc order by query condition, the input parameters are columns.
  225. func (session *Session) Asc(colNames ...string) *Session {
  226. session.Statement.Asc(colNames...)
  227. return session
  228. }
  229. // StoreEngine is only avialble mysql dialect currently
  230. func (session *Session) StoreEngine(storeEngine string) *Session {
  231. session.Statement.StoreEngine = storeEngine
  232. return session
  233. }
  234. // Charset is only avialble mysql dialect currently
  235. func (session *Session) Charset(charset string) *Session {
  236. session.Statement.Charset = charset
  237. return session
  238. }
  239. // Cascade indicates if loading sub Struct
  240. func (session *Session) Cascade(trueOrFalse ...bool) *Session {
  241. if len(trueOrFalse) >= 1 {
  242. session.Statement.UseCascade = trueOrFalse[0]
  243. }
  244. return session
  245. }
  246. // NoCache ask this session do not retrieve data from cache system and
  247. // get data from database directly.
  248. func (session *Session) NoCache() *Session {
  249. session.Statement.UseCache = false
  250. return session
  251. }
  252. // Join join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN
  253. func (session *Session) Join(joinOperator string, tablename interface{}, condition string, args ...interface{}) *Session {
  254. session.Statement.Join(joinOperator, tablename, condition, args...)
  255. return session
  256. }
  257. // GroupBy Generate Group By statement
  258. func (session *Session) GroupBy(keys string) *Session {
  259. session.Statement.GroupBy(keys)
  260. return session
  261. }
  262. // Having Generate Having statement
  263. func (session *Session) Having(conditions string) *Session {
  264. session.Statement.Having(conditions)
  265. return session
  266. }
  267. // DB db return the wrapper of sql.DB
  268. func (session *Session) DB() *core.DB {
  269. if session.db == nil {
  270. session.db = session.Engine.db
  271. session.stmtCache = make(map[uint32]*core.Stmt, 0)
  272. }
  273. return session.db
  274. }
  275. func cleanupProcessorsClosures(slices *[]func(interface{})) {
  276. if len(*slices) > 0 {
  277. *slices = make([]func(interface{}), 0)
  278. }
  279. }
  280. func (session *Session) canCache() bool {
  281. if session.Statement.RefTable == nil ||
  282. session.Statement.JoinStr != "" ||
  283. session.Statement.RawSQL != "" ||
  284. !session.Statement.UseCache ||
  285. session.Statement.IsForUpdate ||
  286. session.Tx != nil ||
  287. len(session.Statement.selectStr) > 0 {
  288. return false
  289. }
  290. return true
  291. }
  292. func (session *Session) doPrepare(sqlStr string) (stmt *core.Stmt, err error) {
  293. crc := crc32.ChecksumIEEE([]byte(sqlStr))
  294. // TODO try hash(sqlStr+len(sqlStr))
  295. var has bool
  296. stmt, has = session.stmtCache[crc]
  297. if !has {
  298. stmt, err = session.DB().Prepare(sqlStr)
  299. if err != nil {
  300. return nil, err
  301. }
  302. session.stmtCache[crc] = stmt
  303. }
  304. return
  305. }
  306. func (session *Session) getField(dataStruct *reflect.Value, key string, table *core.Table, idx int) *reflect.Value {
  307. var col *core.Column
  308. if col = table.GetColumnIdx(key, idx); col == nil {
  309. //session.Engine.logger.Warnf("table %v has no column %v. %v", table.Name, key, table.ColumnsSeq())
  310. return nil
  311. }
  312. fieldValue, err := col.ValueOfV(dataStruct)
  313. if err != nil {
  314. session.Engine.logger.Error(err)
  315. return nil
  316. }
  317. if !fieldValue.IsValid() || !fieldValue.CanSet() {
  318. session.Engine.logger.Warnf("table %v's column %v is not valid or cannot set", table.Name, key)
  319. return nil
  320. }
  321. return fieldValue
  322. }
  323. // Cell cell is a result of one column field
  324. type Cell *interface{}
  325. func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount int,
  326. table *core.Table, newElemFunc func([]string) reflect.Value,
  327. sliceValueSetFunc func(*reflect.Value, core.PK) error) error {
  328. for rows.Next() {
  329. var newValue = newElemFunc(fields)
  330. bean := newValue.Interface()
  331. dataStruct := rValue(bean)
  332. pk, err := session._row2Bean(rows, fields, fieldsCount, bean, &dataStruct, table)
  333. if err != nil {
  334. return err
  335. }
  336. err = sliceValueSetFunc(&newValue, pk)
  337. if err != nil {
  338. return err
  339. }
  340. }
  341. return nil
  342. }
  343. func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount int, bean interface{}) (core.PK, error) {
  344. dataStruct := rValue(bean)
  345. if dataStruct.Kind() != reflect.Struct {
  346. return nil, errors.New("Expected a pointer to a struct")
  347. }
  348. session.Statement.setRefValue(dataStruct)
  349. return session._row2Bean(rows, fields, fieldsCount, bean, &dataStruct, session.Statement.RefTable)
  350. }
  351. func (session *Session) _row2Bean(rows *core.Rows, fields []string, fieldsCount int, bean interface{}, dataStruct *reflect.Value, table *core.Table) (core.PK, error) {
  352. scanResults := make([]interface{}, fieldsCount)
  353. for i := 0; i < len(fields); i++ {
  354. var cell interface{}
  355. scanResults[i] = &cell
  356. }
  357. if err := rows.Scan(scanResults...); err != nil {
  358. return nil, err
  359. }
  360. if b, hasBeforeSet := bean.(BeforeSetProcessor); hasBeforeSet {
  361. for ii, key := range fields {
  362. b.BeforeSet(key, Cell(scanResults[ii].(*interface{})))
  363. }
  364. }
  365. defer func() {
  366. if b, hasAfterSet := bean.(AfterSetProcessor); hasAfterSet {
  367. for ii, key := range fields {
  368. b.AfterSet(key, Cell(scanResults[ii].(*interface{})))
  369. }
  370. }
  371. }()
  372. var tempMap = make(map[string]int)
  373. var pk core.PK
  374. for ii, key := range fields {
  375. var idx int
  376. var ok bool
  377. var lKey = strings.ToLower(key)
  378. if idx, ok = tempMap[lKey]; !ok {
  379. idx = 0
  380. } else {
  381. idx = idx + 1
  382. }
  383. tempMap[lKey] = idx
  384. if fieldValue := session.getField(dataStruct, key, table, idx); fieldValue != nil {
  385. rawValue := reflect.Indirect(reflect.ValueOf(scanResults[ii]))
  386. // if row is null then ignore
  387. if rawValue.Interface() == nil {
  388. continue
  389. }
  390. if fieldValue.CanAddr() {
  391. if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok {
  392. if data, err := value2Bytes(&rawValue); err == nil {
  393. structConvert.FromDB(data)
  394. } else {
  395. session.Engine.logger.Error(err)
  396. }
  397. continue
  398. }
  399. }
  400. if _, ok := fieldValue.Interface().(core.Conversion); ok {
  401. if data, err := value2Bytes(&rawValue); err == nil {
  402. if fieldValue.Kind() == reflect.Ptr && fieldValue.IsNil() {
  403. fieldValue.Set(reflect.New(fieldValue.Type().Elem()))
  404. }
  405. fieldValue.Interface().(core.Conversion).FromDB(data)
  406. } else {
  407. session.Engine.logger.Error(err)
  408. }
  409. continue
  410. }
  411. rawValueType := reflect.TypeOf(rawValue.Interface())
  412. vv := reflect.ValueOf(rawValue.Interface())
  413. col := table.GetColumnIdx(key, idx)
  414. if col.IsPrimaryKey {
  415. pk = append(pk, rawValue.Interface())
  416. }
  417. fieldType := fieldValue.Type()
  418. hasAssigned := false
  419. if col.SQLType.IsJson() {
  420. var bs []byte
  421. if rawValueType.Kind() == reflect.String {
  422. bs = []byte(vv.String())
  423. } else if rawValueType.ConvertibleTo(core.BytesType) {
  424. bs = vv.Bytes()
  425. } else {
  426. return nil, fmt.Errorf("unsupported database data type: %s %v", key, rawValueType.Kind())
  427. }
  428. hasAssigned = true
  429. if len(bs) > 0 {
  430. if fieldValue.CanAddr() {
  431. err := json.Unmarshal(bs, fieldValue.Addr().Interface())
  432. if err != nil {
  433. session.Engine.logger.Error(key, err)
  434. return nil, err
  435. }
  436. } else {
  437. x := reflect.New(fieldType)
  438. err := json.Unmarshal(bs, x.Interface())
  439. if err != nil {
  440. session.Engine.logger.Error(key, err)
  441. return nil, err
  442. }
  443. fieldValue.Set(x.Elem())
  444. }
  445. }
  446. continue
  447. }
  448. switch fieldType.Kind() {
  449. case reflect.Complex64, reflect.Complex128:
  450. // TODO: reimplement this
  451. var bs []byte
  452. if rawValueType.Kind() == reflect.String {
  453. bs = []byte(vv.String())
  454. } else if rawValueType.ConvertibleTo(core.BytesType) {
  455. bs = vv.Bytes()
  456. }
  457. hasAssigned = true
  458. if len(bs) > 0 {
  459. if fieldValue.CanAddr() {
  460. err := json.Unmarshal(bs, fieldValue.Addr().Interface())
  461. if err != nil {
  462. session.Engine.logger.Error(err)
  463. return nil, err
  464. }
  465. } else {
  466. x := reflect.New(fieldType)
  467. err := json.Unmarshal(bs, x.Interface())
  468. if err != nil {
  469. session.Engine.logger.Error(err)
  470. return nil, err
  471. }
  472. fieldValue.Set(x.Elem())
  473. }
  474. }
  475. case reflect.Slice, reflect.Array:
  476. switch rawValueType.Kind() {
  477. case reflect.Slice, reflect.Array:
  478. switch rawValueType.Elem().Kind() {
  479. case reflect.Uint8:
  480. if fieldType.Elem().Kind() == reflect.Uint8 {
  481. hasAssigned = true
  482. fieldValue.Set(vv)
  483. }
  484. }
  485. }
  486. case reflect.String:
  487. if rawValueType.Kind() == reflect.String {
  488. hasAssigned = true
  489. fieldValue.SetString(vv.String())
  490. }
  491. case reflect.Bool:
  492. if rawValueType.Kind() == reflect.Bool {
  493. hasAssigned = true
  494. fieldValue.SetBool(vv.Bool())
  495. }
  496. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  497. switch rawValueType.Kind() {
  498. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  499. hasAssigned = true
  500. fieldValue.SetInt(vv.Int())
  501. }
  502. case reflect.Float32, reflect.Float64:
  503. switch rawValueType.Kind() {
  504. case reflect.Float32, reflect.Float64:
  505. hasAssigned = true
  506. fieldValue.SetFloat(vv.Float())
  507. }
  508. case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
  509. switch rawValueType.Kind() {
  510. case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
  511. hasAssigned = true
  512. fieldValue.SetUint(vv.Uint())
  513. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  514. hasAssigned = true
  515. fieldValue.SetUint(uint64(vv.Int()))
  516. }
  517. case reflect.Struct:
  518. if fieldType.ConvertibleTo(core.TimeType) {
  519. if rawValueType == core.TimeType {
  520. hasAssigned = true
  521. t := vv.Convert(core.TimeType).Interface().(time.Time)
  522. z, _ := t.Zone()
  523. dbTZ := session.Engine.DatabaseTZ
  524. if dbTZ == nil {
  525. if session.Engine.dialect.DBType() == core.SQLITE {
  526. dbTZ = time.UTC
  527. } else {
  528. dbTZ = time.Local
  529. }
  530. }
  531. // set new location if database don't save timezone or give an incorrect timezone
  532. if len(z) == 0 || t.Year() == 0 || t.Location().String() != dbTZ.String() { // !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(), dbTZ)
  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. fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
  544. // t = fieldValue.Interface().(time.Time)
  545. // z, _ = t.Zone()
  546. // session.Engine.LogDebug("fieldValue key[%v]: %v | zone: %v | location: %+v\n", key, t, z, *t.Location())
  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. session.Engine.logger.Error("sql.Sanner error:", err.Error())
  587. hasAssigned = false
  588. }
  589. } else if col.SQLType.IsJson() {
  590. if rawValueType.Kind() == reflect.String {
  591. hasAssigned = true
  592. x := reflect.New(fieldType)
  593. if len([]byte(vv.String())) > 0 {
  594. err := json.Unmarshal([]byte(vv.String()), x.Interface())
  595. if err != nil {
  596. session.Engine.logger.Error(err)
  597. return nil, err
  598. }
  599. fieldValue.Set(x.Elem())
  600. }
  601. } else if rawValueType.Kind() == reflect.Slice {
  602. hasAssigned = true
  603. x := reflect.New(fieldType)
  604. if len(vv.Bytes()) > 0 {
  605. err := json.Unmarshal(vv.Bytes(), x.Interface())
  606. if err != nil {
  607. session.Engine.logger.Error(err)
  608. return nil, err
  609. }
  610. fieldValue.Set(x.Elem())
  611. }
  612. }
  613. } else if session.Statement.UseCascade {
  614. table := session.Engine.autoMapType(*fieldValue)
  615. if table != nil {
  616. hasAssigned = true
  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 nil, err
  659. }
  660. if has {
  661. //v := structInter.Elem().Interface()
  662. //fieldValue.Set(reflect.ValueOf(v))
  663. fieldValue.Set(structInter.Elem())
  664. } else {
  665. return nil, errors.New("cascade obj is not exist")
  666. }
  667. }
  668. } else {
  669. session.Engine.logger.Error("unsupported struct type in Scan: ", fieldValue.Type().String())
  670. }
  671. }
  672. case reflect.Ptr:
  673. // !nashtsai! TODO merge duplicated codes above
  674. //typeStr := fieldType.String()
  675. switch fieldType {
  676. // following types case matching ptr's native type, therefore assign ptr directly
  677. case core.PtrStringType:
  678. if rawValueType.Kind() == reflect.String {
  679. x := vv.String()
  680. hasAssigned = true
  681. fieldValue.Set(reflect.ValueOf(&x))
  682. }
  683. case core.PtrBoolType:
  684. if rawValueType.Kind() == reflect.Bool {
  685. x := vv.Bool()
  686. hasAssigned = true
  687. fieldValue.Set(reflect.ValueOf(&x))
  688. }
  689. case core.PtrTimeType:
  690. if rawValueType == core.PtrTimeType {
  691. hasAssigned = true
  692. var x = rawValue.Interface().(time.Time)
  693. fieldValue.Set(reflect.ValueOf(&x))
  694. }
  695. case core.PtrFloat64Type:
  696. if rawValueType.Kind() == reflect.Float64 {
  697. x := vv.Float()
  698. hasAssigned = true
  699. fieldValue.Set(reflect.ValueOf(&x))
  700. }
  701. case core.PtrUint64Type:
  702. if rawValueType.Kind() == reflect.Int64 {
  703. var x = uint64(vv.Int())
  704. hasAssigned = true
  705. fieldValue.Set(reflect.ValueOf(&x))
  706. }
  707. case core.PtrInt64Type:
  708. if rawValueType.Kind() == reflect.Int64 {
  709. x := vv.Int()
  710. hasAssigned = true
  711. fieldValue.Set(reflect.ValueOf(&x))
  712. }
  713. case core.PtrFloat32Type:
  714. if rawValueType.Kind() == reflect.Float64 {
  715. var x = float32(vv.Float())
  716. hasAssigned = true
  717. fieldValue.Set(reflect.ValueOf(&x))
  718. }
  719. case core.PtrIntType:
  720. if rawValueType.Kind() == reflect.Int64 {
  721. var x = int(vv.Int())
  722. hasAssigned = true
  723. fieldValue.Set(reflect.ValueOf(&x))
  724. }
  725. case core.PtrInt32Type:
  726. if rawValueType.Kind() == reflect.Int64 {
  727. var x = int32(vv.Int())
  728. hasAssigned = true
  729. fieldValue.Set(reflect.ValueOf(&x))
  730. }
  731. case core.PtrInt8Type:
  732. if rawValueType.Kind() == reflect.Int64 {
  733. var x = int8(vv.Int())
  734. hasAssigned = true
  735. fieldValue.Set(reflect.ValueOf(&x))
  736. }
  737. case core.PtrInt16Type:
  738. if rawValueType.Kind() == reflect.Int64 {
  739. var x = int16(vv.Int())
  740. hasAssigned = true
  741. fieldValue.Set(reflect.ValueOf(&x))
  742. }
  743. case core.PtrUintType:
  744. if rawValueType.Kind() == reflect.Int64 {
  745. var x = uint(vv.Int())
  746. hasAssigned = true
  747. fieldValue.Set(reflect.ValueOf(&x))
  748. }
  749. case core.PtrUint32Type:
  750. if rawValueType.Kind() == reflect.Int64 {
  751. var x = uint32(vv.Int())
  752. hasAssigned = true
  753. fieldValue.Set(reflect.ValueOf(&x))
  754. }
  755. case core.Uint8Type:
  756. if rawValueType.Kind() == reflect.Int64 {
  757. var x = uint8(vv.Int())
  758. hasAssigned = true
  759. fieldValue.Set(reflect.ValueOf(&x))
  760. }
  761. case core.Uint16Type:
  762. if rawValueType.Kind() == reflect.Int64 {
  763. var x = uint16(vv.Int())
  764. hasAssigned = true
  765. fieldValue.Set(reflect.ValueOf(&x))
  766. }
  767. case core.Complex64Type:
  768. var x complex64
  769. if len([]byte(vv.String())) > 0 {
  770. err := json.Unmarshal([]byte(vv.String()), &x)
  771. if err != nil {
  772. session.Engine.logger.Error(err)
  773. } else {
  774. fieldValue.Set(reflect.ValueOf(&x))
  775. }
  776. }
  777. hasAssigned = true
  778. case core.Complex128Type:
  779. var x complex128
  780. if len([]byte(vv.String())) > 0 {
  781. err := json.Unmarshal([]byte(vv.String()), &x)
  782. if err != nil {
  783. session.Engine.logger.Error(err)
  784. } else {
  785. fieldValue.Set(reflect.ValueOf(&x))
  786. }
  787. }
  788. hasAssigned = true
  789. } // switch fieldType
  790. // default:
  791. // session.Engine.LogError("unsupported type in Scan: ", reflect.TypeOf(v).String())
  792. } // switch fieldType.Kind()
  793. // !nashtsai! for value can't be assigned directly fallback to convert to []byte then back to value
  794. if !hasAssigned {
  795. data, err := value2Bytes(&rawValue)
  796. if err == nil {
  797. session.bytes2Value(col, fieldValue, data)
  798. } else {
  799. session.Engine.logger.Error(err.Error())
  800. }
  801. }
  802. }
  803. }
  804. return pk, nil
  805. }
  806. func (session *Session) queryPreprocess(sqlStr *string, paramStr ...interface{}) {
  807. for _, filter := range session.Engine.dialect.Filters() {
  808. *sqlStr = filter.Do(*sqlStr, session.Engine.dialect, session.Statement.RefTable)
  809. }
  810. session.saveLastSQL(*sqlStr, paramStr...)
  811. }
  812. func (session *Session) str2Time(col *core.Column, data string) (outTime time.Time, outErr error) {
  813. sdata := strings.TrimSpace(data)
  814. var x time.Time
  815. var err error
  816. if sdata == "0000-00-00 00:00:00" ||
  817. sdata == "0001-01-01 00:00:00" {
  818. } else if !strings.ContainsAny(sdata, "- :") { // !nashtsai! has only found that mymysql driver is using this for time type column
  819. // time stamp
  820. sd, err := strconv.ParseInt(sdata, 10, 64)
  821. if err == nil {
  822. x = time.Unix(sd, 0)
  823. // !nashtsai! HACK mymysql driver is causing Local location being change to CHAT and cause wrong time conversion
  824. if col.TimeZone == nil {
  825. x = x.In(session.Engine.TZLocation)
  826. } else {
  827. x = x.In(col.TimeZone)
  828. }
  829. session.Engine.logger.Debugf("time(0) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  830. } else {
  831. session.Engine.logger.Debugf("time(0) err key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  832. }
  833. } else if len(sdata) > 19 && strings.Contains(sdata, "-") {
  834. x, err = time.ParseInLocation(time.RFC3339Nano, sdata, session.Engine.TZLocation)
  835. session.Engine.logger.Debugf("time(1) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  836. if err != nil {
  837. x, err = time.ParseInLocation("2006-01-02 15:04:05.999999999", sdata, session.Engine.TZLocation)
  838. session.Engine.logger.Debugf("time(2) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  839. }
  840. if err != nil {
  841. x, err = time.ParseInLocation("2006-01-02 15:04:05.9999999 Z07:00", sdata, session.Engine.TZLocation)
  842. session.Engine.logger.Debugf("time(3) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  843. }
  844. } else if len(sdata) == 19 && strings.Contains(sdata, "-") {
  845. x, err = time.ParseInLocation("2006-01-02 15:04:05", sdata, session.Engine.TZLocation)
  846. session.Engine.logger.Debugf("time(4) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  847. } else if len(sdata) == 10 && sdata[4] == '-' && sdata[7] == '-' {
  848. x, err = time.ParseInLocation("2006-01-02", sdata, session.Engine.TZLocation)
  849. session.Engine.logger.Debugf("time(5) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  850. } else if col.SQLType.Name == core.Time {
  851. if strings.Contains(sdata, " ") {
  852. ssd := strings.Split(sdata, " ")
  853. sdata = ssd[1]
  854. }
  855. sdata = strings.TrimSpace(sdata)
  856. if session.Engine.dialect.DBType() == core.MYSQL && len(sdata) > 8 {
  857. sdata = sdata[len(sdata)-8:]
  858. }
  859. st := fmt.Sprintf("2006-01-02 %v", sdata)
  860. x, err = time.ParseInLocation("2006-01-02 15:04:05", st, session.Engine.TZLocation)
  861. session.Engine.logger.Debugf("time(6) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
  862. } else {
  863. outErr = fmt.Errorf("unsupported time format %v", sdata)
  864. return
  865. }
  866. if err != nil {
  867. outErr = fmt.Errorf("unsupported time format %v: %v", sdata, err)
  868. return
  869. }
  870. outTime = x
  871. return
  872. }
  873. func (session *Session) byte2Time(col *core.Column, data []byte) (outTime time.Time, outErr error) {
  874. return session.str2Time(col, string(data))
  875. }
  876. // convert a db data([]byte) to a field value
  877. func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value, data []byte) error {
  878. if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok {
  879. return structConvert.FromDB(data)
  880. }
  881. if structConvert, ok := fieldValue.Interface().(core.Conversion); ok {
  882. return structConvert.FromDB(data)
  883. }
  884. var v interface{}
  885. key := col.Name
  886. fieldType := fieldValue.Type()
  887. switch fieldType.Kind() {
  888. case reflect.Complex64, reflect.Complex128:
  889. x := reflect.New(fieldType)
  890. if len(data) > 0 {
  891. err := json.Unmarshal(data, x.Interface())
  892. if err != nil {
  893. session.Engine.logger.Error(err)
  894. return err
  895. }
  896. fieldValue.Set(x.Elem())
  897. }
  898. case reflect.Slice, reflect.Array, reflect.Map:
  899. v = data
  900. t := fieldType.Elem()
  901. k := t.Kind()
  902. if col.SQLType.IsText() {
  903. x := reflect.New(fieldType)
  904. if len(data) > 0 {
  905. err := json.Unmarshal(data, x.Interface())
  906. if err != nil {
  907. session.Engine.logger.Error(err)
  908. return err
  909. }
  910. fieldValue.Set(x.Elem())
  911. }
  912. } else if col.SQLType.IsBlob() {
  913. if k == reflect.Uint8 {
  914. fieldValue.Set(reflect.ValueOf(v))
  915. } else {
  916. x := reflect.New(fieldType)
  917. if len(data) > 0 {
  918. err := json.Unmarshal(data, x.Interface())
  919. if err != nil {
  920. session.Engine.logger.Error(err)
  921. return err
  922. }
  923. fieldValue.Set(x.Elem())
  924. }
  925. }
  926. } else {
  927. return ErrUnSupportedType
  928. }
  929. case reflect.String:
  930. fieldValue.SetString(string(data))
  931. case reflect.Bool:
  932. d := string(data)
  933. v, err := strconv.ParseBool(d)
  934. if err != nil {
  935. return fmt.Errorf("arg %v as bool: %s", key, err.Error())
  936. }
  937. fieldValue.Set(reflect.ValueOf(v))
  938. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  939. sdata := string(data)
  940. var x int64
  941. var err error
  942. // for mysql, when use bit, it returned \x01
  943. if col.SQLType.Name == core.Bit &&
  944. session.Engine.dialect.DBType() == core.MYSQL { // !nashtsai! TODO dialect needs to provide conversion interface API
  945. if len(data) == 1 {
  946. x = int64(data[0])
  947. } else {
  948. x = 0
  949. }
  950. } else if strings.HasPrefix(sdata, "0x") {
  951. x, err = strconv.ParseInt(sdata, 16, 64)
  952. } else if strings.HasPrefix(sdata, "0") {
  953. x, err = strconv.ParseInt(sdata, 8, 64)
  954. } else if strings.EqualFold(sdata, "true") {
  955. x = 1
  956. } else if strings.EqualFold(sdata, "false") {
  957. x = 0
  958. } else {
  959. x, err = strconv.ParseInt(sdata, 10, 64)
  960. }
  961. if err != nil {
  962. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  963. }
  964. fieldValue.SetInt(x)
  965. case reflect.Float32, reflect.Float64:
  966. x, err := strconv.ParseFloat(string(data), 64)
  967. if err != nil {
  968. return fmt.Errorf("arg %v as float64: %s", key, err.Error())
  969. }
  970. fieldValue.SetFloat(x)
  971. case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
  972. x, err := strconv.ParseUint(string(data), 10, 64)
  973. if err != nil {
  974. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  975. }
  976. fieldValue.SetUint(x)
  977. //Currently only support Time type
  978. case reflect.Struct:
  979. // !<winxxp>! 增加支持sql.Scanner接口的结构,如sql.NullString
  980. if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
  981. if err := nulVal.Scan(data); err != nil {
  982. return fmt.Errorf("sql.Scan(%v) failed: %s ", data, err.Error())
  983. }
  984. } else {
  985. if fieldType.ConvertibleTo(core.TimeType) {
  986. x, err := session.byte2Time(col, data)
  987. if err != nil {
  988. return err
  989. }
  990. v = x
  991. fieldValue.Set(reflect.ValueOf(v).Convert(fieldType))
  992. } else if session.Statement.UseCascade {
  993. table := session.Engine.autoMapType(*fieldValue)
  994. if table != nil {
  995. // TODO: current only support 1 primary key
  996. if len(table.PrimaryKeys) > 1 {
  997. panic("unsupported composited primary key cascade")
  998. }
  999. var pk = make(core.PK, len(table.PrimaryKeys))
  1000. rawValueType := table.ColumnType(table.PKColumns()[0].FieldName)
  1001. var err error
  1002. pk[0], err = str2PK(string(data), rawValueType)
  1003. if err != nil {
  1004. return err
  1005. }
  1006. if !isPKZero(pk) {
  1007. // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
  1008. // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
  1009. // property to be fetched lazily
  1010. structInter := reflect.New(fieldValue.Type())
  1011. newsession := session.Engine.NewSession()
  1012. defer newsession.Close()
  1013. has, err := newsession.Id(pk).NoCascade().Get(structInter.Interface())
  1014. if err != nil {
  1015. return err
  1016. }
  1017. if has {
  1018. v = structInter.Elem().Interface()
  1019. fieldValue.Set(reflect.ValueOf(v))
  1020. } else {
  1021. return errors.New("cascade obj is not exist")
  1022. }
  1023. }
  1024. } else {
  1025. return fmt.Errorf("unsupported struct type in Scan: %s", fieldValue.Type().String())
  1026. }
  1027. }
  1028. }
  1029. case reflect.Ptr:
  1030. // !nashtsai! TODO merge duplicated codes above
  1031. //typeStr := fieldType.String()
  1032. switch fieldType.Elem().Kind() {
  1033. // case "*string":
  1034. case core.StringType.Kind():
  1035. x := string(data)
  1036. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  1037. // case "*bool":
  1038. case core.BoolType.Kind():
  1039. d := string(data)
  1040. v, err := strconv.ParseBool(d)
  1041. if err != nil {
  1042. return fmt.Errorf("arg %v as bool: %s", key, err.Error())
  1043. }
  1044. fieldValue.Set(reflect.ValueOf(&v).Convert(fieldType))
  1045. // case "*complex64":
  1046. case core.Complex64Type.Kind():
  1047. var x complex64
  1048. if len(data) > 0 {
  1049. err := json.Unmarshal(data, &x)
  1050. if err != nil {
  1051. session.Engine.logger.Error(err)
  1052. return err
  1053. }
  1054. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  1055. }
  1056. // case "*complex128":
  1057. case core.Complex128Type.Kind():
  1058. var x complex128
  1059. if len(data) > 0 {
  1060. err := json.Unmarshal(data, &x)
  1061. if err != nil {
  1062. session.Engine.logger.Error(err)
  1063. return err
  1064. }
  1065. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  1066. }
  1067. // case "*float64":
  1068. case core.Float64Type.Kind():
  1069. x, err := strconv.ParseFloat(string(data), 64)
  1070. if err != nil {
  1071. return fmt.Errorf("arg %v as float64: %s", key, err.Error())
  1072. }
  1073. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  1074. // case "*float32":
  1075. case core.Float32Type.Kind():
  1076. var x float32
  1077. x1, err := strconv.ParseFloat(string(data), 32)
  1078. if err != nil {
  1079. return fmt.Errorf("arg %v as float32: %s", key, err.Error())
  1080. }
  1081. x = float32(x1)
  1082. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  1083. // case "*uint64":
  1084. case core.Uint64Type.Kind():
  1085. var x uint64
  1086. x, err := strconv.ParseUint(string(data), 10, 64)
  1087. if err != nil {
  1088. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  1089. }
  1090. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  1091. // case "*uint":
  1092. case core.UintType.Kind():
  1093. var x uint
  1094. x1, err := strconv.ParseUint(string(data), 10, 64)
  1095. if err != nil {
  1096. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  1097. }
  1098. x = uint(x1)
  1099. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  1100. // case "*uint32":
  1101. case core.Uint32Type.Kind():
  1102. var x uint32
  1103. x1, err := strconv.ParseUint(string(data), 10, 64)
  1104. if err != nil {
  1105. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  1106. }
  1107. x = uint32(x1)
  1108. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  1109. // case "*uint8":
  1110. case core.Uint8Type.Kind():
  1111. var x uint8
  1112. x1, err := strconv.ParseUint(string(data), 10, 64)
  1113. if err != nil {
  1114. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  1115. }
  1116. x = uint8(x1)
  1117. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  1118. // case "*uint16":
  1119. case core.Uint16Type.Kind():
  1120. var x uint16
  1121. x1, err := strconv.ParseUint(string(data), 10, 64)
  1122. if err != nil {
  1123. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  1124. }
  1125. x = uint16(x1)
  1126. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  1127. // case "*int64":
  1128. case core.Int64Type.Kind():
  1129. sdata := string(data)
  1130. var x int64
  1131. var err error
  1132. // for mysql, when use bit, it returned \x01
  1133. if col.SQLType.Name == core.Bit &&
  1134. strings.Contains(session.Engine.DriverName(), "mysql") {
  1135. if len(data) == 1 {
  1136. x = int64(data[0])
  1137. } else {
  1138. x = 0
  1139. }
  1140. } else if strings.HasPrefix(sdata, "0x") {
  1141. x, err = strconv.ParseInt(sdata, 16, 64)
  1142. } else if strings.HasPrefix(sdata, "0") {
  1143. x, err = strconv.ParseInt(sdata, 8, 64)
  1144. } else {
  1145. x, err = strconv.ParseInt(sdata, 10, 64)
  1146. }
  1147. if err != nil {
  1148. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  1149. }
  1150. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  1151. // case "*int":
  1152. case core.IntType.Kind():
  1153. sdata := string(data)
  1154. var x int
  1155. var x1 int64
  1156. var err error
  1157. // for mysql, when use bit, it returned \x01
  1158. if col.SQLType.Name == core.Bit &&
  1159. strings.Contains(session.Engine.DriverName(), "mysql") {
  1160. if len(data) == 1 {
  1161. x = int(data[0])
  1162. } else {
  1163. x = 0
  1164. }
  1165. } else if strings.HasPrefix(sdata, "0x") {
  1166. x1, err = strconv.ParseInt(sdata, 16, 64)
  1167. x = int(x1)
  1168. } else if strings.HasPrefix(sdata, "0") {
  1169. x1, err = strconv.ParseInt(sdata, 8, 64)
  1170. x = int(x1)
  1171. } else {
  1172. x1, err = strconv.ParseInt(sdata, 10, 64)
  1173. x = int(x1)
  1174. }
  1175. if err != nil {
  1176. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  1177. }
  1178. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  1179. // case "*int32":
  1180. case core.Int32Type.Kind():
  1181. sdata := string(data)
  1182. var x int32
  1183. var x1 int64
  1184. var err error
  1185. // for mysql, when use bit, it returned \x01
  1186. if col.SQLType.Name == core.Bit &&
  1187. session.Engine.dialect.DBType() == core.MYSQL {
  1188. if len(data) == 1 {
  1189. x = int32(data[0])
  1190. } else {
  1191. x = 0
  1192. }
  1193. } else if strings.HasPrefix(sdata, "0x") {
  1194. x1, err = strconv.ParseInt(sdata, 16, 64)
  1195. x = int32(x1)
  1196. } else if strings.HasPrefix(sdata, "0") {
  1197. x1, err = strconv.ParseInt(sdata, 8, 64)
  1198. x = int32(x1)
  1199. } else {
  1200. x1, err = strconv.ParseInt(sdata, 10, 64)
  1201. x = int32(x1)
  1202. }
  1203. if err != nil {
  1204. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  1205. }
  1206. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  1207. // case "*int8":
  1208. case core.Int8Type.Kind():
  1209. sdata := string(data)
  1210. var x int8
  1211. var x1 int64
  1212. var err error
  1213. // for mysql, when use bit, it returned \x01
  1214. if col.SQLType.Name == core.Bit &&
  1215. strings.Contains(session.Engine.DriverName(), "mysql") {
  1216. if len(data) == 1 {
  1217. x = int8(data[0])
  1218. } else {
  1219. x = 0
  1220. }
  1221. } else if strings.HasPrefix(sdata, "0x") {
  1222. x1, err = strconv.ParseInt(sdata, 16, 64)
  1223. x = int8(x1)
  1224. } else if strings.HasPrefix(sdata, "0") {
  1225. x1, err = strconv.ParseInt(sdata, 8, 64)
  1226. x = int8(x1)
  1227. } else {
  1228. x1, err = strconv.ParseInt(sdata, 10, 64)
  1229. x = int8(x1)
  1230. }
  1231. if err != nil {
  1232. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  1233. }
  1234. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  1235. // case "*int16":
  1236. case core.Int16Type.Kind():
  1237. sdata := string(data)
  1238. var x int16
  1239. var x1 int64
  1240. var err error
  1241. // for mysql, when use bit, it returned \x01
  1242. if col.SQLType.Name == core.Bit &&
  1243. strings.Contains(session.Engine.DriverName(), "mysql") {
  1244. if len(data) == 1 {
  1245. x = int16(data[0])
  1246. } else {
  1247. x = 0
  1248. }
  1249. } else if strings.HasPrefix(sdata, "0x") {
  1250. x1, err = strconv.ParseInt(sdata, 16, 64)
  1251. x = int16(x1)
  1252. } else if strings.HasPrefix(sdata, "0") {
  1253. x1, err = strconv.ParseInt(sdata, 8, 64)
  1254. x = int16(x1)
  1255. } else {
  1256. x1, err = strconv.ParseInt(sdata, 10, 64)
  1257. x = int16(x1)
  1258. }
  1259. if err != nil {
  1260. return fmt.Errorf("arg %v as int: %s", key, err.Error())
  1261. }
  1262. fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
  1263. // case "*SomeStruct":
  1264. case reflect.Struct:
  1265. switch fieldType {
  1266. // case "*.time.Time":
  1267. case core.PtrTimeType:
  1268. x, err := session.byte2Time(col, data)
  1269. if err != nil {
  1270. return err
  1271. }
  1272. v = x
  1273. fieldValue.Set(reflect.ValueOf(&x))
  1274. default:
  1275. if session.Statement.UseCascade {
  1276. structInter := reflect.New(fieldType.Elem())
  1277. table := session.Engine.autoMapType(structInter.Elem())
  1278. if table != nil {
  1279. if len(table.PrimaryKeys) > 1 {
  1280. panic("unsupported composited primary key cascade")
  1281. }
  1282. var pk = make(core.PK, len(table.PrimaryKeys))
  1283. var err error
  1284. rawValueType := table.ColumnType(table.PKColumns()[0].FieldName)
  1285. pk[0], err = str2PK(string(data), rawValueType)
  1286. if err != nil {
  1287. return err
  1288. }
  1289. if !isPKZero(pk) {
  1290. // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
  1291. // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
  1292. // property to be fetched lazily
  1293. newsession := session.Engine.NewSession()
  1294. defer newsession.Close()
  1295. has, err := newsession.Id(pk).NoCascade().Get(structInter.Interface())
  1296. if err != nil {
  1297. return err
  1298. }
  1299. if has {
  1300. v = structInter.Interface()
  1301. fieldValue.Set(reflect.ValueOf(v))
  1302. } else {
  1303. return errors.New("cascade obj is not exist")
  1304. }
  1305. }
  1306. }
  1307. } else {
  1308. return fmt.Errorf("unsupported struct type in Scan: %s", fieldValue.Type().String())
  1309. }
  1310. }
  1311. default:
  1312. return fmt.Errorf("unsupported type in Scan: %s", fieldValue.Type().String())
  1313. }
  1314. default:
  1315. return fmt.Errorf("unsupported type in Scan: %s", fieldValue.Type().String())
  1316. }
  1317. return nil
  1318. }
  1319. // convert a field value of a struct to interface for put into db
  1320. func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Value) (interface{}, error) {
  1321. if fieldValue.CanAddr() {
  1322. if fieldConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok {
  1323. data, err := fieldConvert.ToDB()
  1324. if err != nil {
  1325. return 0, err
  1326. }
  1327. if col.SQLType.IsBlob() {
  1328. return data, nil
  1329. }
  1330. return string(data), nil
  1331. }
  1332. }
  1333. if fieldConvert, ok := fieldValue.Interface().(core.Conversion); ok {
  1334. data, err := fieldConvert.ToDB()
  1335. if err != nil {
  1336. return 0, err
  1337. }
  1338. if col.SQLType.IsBlob() {
  1339. return data, nil
  1340. }
  1341. return string(data), nil
  1342. }
  1343. fieldType := fieldValue.Type()
  1344. k := fieldType.Kind()
  1345. if k == reflect.Ptr {
  1346. if fieldValue.IsNil() {
  1347. return nil, nil
  1348. } else if !fieldValue.IsValid() {
  1349. session.Engine.logger.Warn("the field[", col.FieldName, "] is invalid")
  1350. return nil, nil
  1351. } else {
  1352. // !nashtsai! deference pointer type to instance type
  1353. fieldValue = fieldValue.Elem()
  1354. fieldType = fieldValue.Type()
  1355. k = fieldType.Kind()
  1356. }
  1357. }
  1358. switch k {
  1359. case reflect.Bool:
  1360. return fieldValue.Bool(), nil
  1361. case reflect.String:
  1362. return fieldValue.String(), nil
  1363. case reflect.Struct:
  1364. if fieldType.ConvertibleTo(core.TimeType) {
  1365. t := fieldValue.Convert(core.TimeType).Interface().(time.Time)
  1366. if session.Engine.dialect.DBType() == core.MSSQL {
  1367. if t.IsZero() {
  1368. return nil, nil
  1369. }
  1370. }
  1371. tf := session.Engine.FormatTime(col.SQLType.Name, t)
  1372. return tf, nil
  1373. }
  1374. if !col.SQLType.IsJson() {
  1375. // !<winxxp>! 增加支持driver.Valuer接口的结构,如sql.NullString
  1376. if v, ok := fieldValue.Interface().(driver.Valuer); ok {
  1377. return v.Value()
  1378. }
  1379. fieldTable := session.Engine.autoMapType(fieldValue)
  1380. if len(fieldTable.PrimaryKeys) == 1 {
  1381. pkField := reflect.Indirect(fieldValue).FieldByName(fieldTable.PKColumns()[0].FieldName)
  1382. return pkField.Interface(), nil
  1383. }
  1384. return 0, fmt.Errorf("no primary key for col %v", col.Name)
  1385. }
  1386. if col.SQLType.IsText() {
  1387. bytes, err := json.Marshal(fieldValue.Interface())
  1388. if err != nil {
  1389. session.Engine.logger.Error(err)
  1390. return 0, err
  1391. }
  1392. return string(bytes), nil
  1393. } else if col.SQLType.IsBlob() {
  1394. bytes, err := json.Marshal(fieldValue.Interface())
  1395. if err != nil {
  1396. session.Engine.logger.Error(err)
  1397. return 0, err
  1398. }
  1399. return bytes, nil
  1400. }
  1401. return nil, fmt.Errorf("Unsupported type %v", fieldValue.Type())
  1402. case reflect.Complex64, reflect.Complex128:
  1403. bytes, err := json.Marshal(fieldValue.Interface())
  1404. if err != nil {
  1405. session.Engine.logger.Error(err)
  1406. return 0, err
  1407. }
  1408. return string(bytes), nil
  1409. case reflect.Array, reflect.Slice, reflect.Map:
  1410. if !fieldValue.IsValid() {
  1411. return fieldValue.Interface(), nil
  1412. }
  1413. if col.SQLType.IsText() {
  1414. bytes, err := json.Marshal(fieldValue.Interface())
  1415. if err != nil {
  1416. session.Engine.logger.Error(err)
  1417. return 0, err
  1418. }
  1419. return string(bytes), nil
  1420. } else if col.SQLType.IsBlob() {
  1421. var bytes []byte
  1422. var err error
  1423. if (k == reflect.Array || k == reflect.Slice) &&
  1424. (fieldValue.Type().Elem().Kind() == reflect.Uint8) {
  1425. bytes = fieldValue.Bytes()
  1426. } else {
  1427. bytes, err = json.Marshal(fieldValue.Interface())
  1428. if err != nil {
  1429. session.Engine.logger.Error(err)
  1430. return 0, err
  1431. }
  1432. }
  1433. return bytes, nil
  1434. }
  1435. return nil, ErrUnSupportedType
  1436. case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
  1437. return int64(fieldValue.Uint()), nil
  1438. default:
  1439. return fieldValue.Interface(), nil
  1440. }
  1441. }
  1442. // saveLastSQL stores executed query information
  1443. func (session *Session) saveLastSQL(sql string, args ...interface{}) {
  1444. session.lastSQL = sql
  1445. session.lastSQLArgs = args
  1446. session.Engine.logSQL(sql, args...)
  1447. }
  1448. // LastSQL returns last query information
  1449. func (session *Session) LastSQL() (string, []interface{}) {
  1450. return session.lastSQL, session.lastSQLArgs
  1451. }
  1452. // tbName get some table's table name
  1453. func (session *Session) tbNameNoSchema(table *core.Table) string {
  1454. if len(session.Statement.AltTableName) > 0 {
  1455. return session.Statement.AltTableName
  1456. }
  1457. return table.Name
  1458. }
  1459. // Unscoped always disable struct tag "deleted"
  1460. func (session *Session) Unscoped() *Session {
  1461. session.Statement.Unscoped()
  1462. return session
  1463. }