PageRenderTime 1732ms CodeModel.GetById 46ms RepoModel.GetById 4ms app.codeStats 0ms

/server/src/github.com/go-xorm/xorm/engine.go

https://gitlab.com/sun-slaven/just_bs
Go | 1454 lines | 1420 code | 20 blank | 14 comment | 8 complexity | 93b1e71177df94bbfa709ec389c8a33d MD5 | raw file
  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. "bufio"
  7. "bytes"
  8. "database/sql"
  9. "encoding/gob"
  10. "errors"
  11. "fmt"
  12. "io"
  13. "os"
  14. "reflect"
  15. "strconv"
  16. "strings"
  17. "sync"
  18. "time"
  19. "github.com/go-xorm/core"
  20. )
  21. // Engine is the major struct of xorm, it means a database manager.
  22. // Commonly, an application only need one engine
  23. type Engine struct {
  24. db *core.DB
  25. dialect core.Dialect
  26. ColumnMapper core.IMapper
  27. TableMapper core.IMapper
  28. TagIdentifier string
  29. Tables map[reflect.Type]*core.Table
  30. mutex *sync.RWMutex
  31. Cacher core.Cacher
  32. ShowSQL bool
  33. // !nashtsai! TODO ought to deprecate these but having logger to control its log level
  34. ShowInfo bool
  35. ShowErr bool
  36. ShowDebug bool
  37. ShowWarn bool
  38. // --227
  39. Logger core.ILogger
  40. TZLocation *time.Location
  41. disableGlobalCache bool
  42. }
  43. func (engine *Engine) SetLogger(logger core.ILogger) {
  44. engine.Logger = logger
  45. engine.dialect.SetLogger(logger)
  46. }
  47. func (engine *Engine) SetDisableGlobalCache(disable bool) {
  48. if engine.disableGlobalCache != disable {
  49. engine.disableGlobalCache = disable
  50. }
  51. }
  52. func (engine *Engine) DriverName() string {
  53. return engine.dialect.DriverName()
  54. }
  55. func (engine *Engine) DataSourceName() string {
  56. return engine.dialect.DataSourceName()
  57. }
  58. func (engine *Engine) SetMapper(mapper core.IMapper) {
  59. engine.SetTableMapper(mapper)
  60. engine.SetColumnMapper(mapper)
  61. }
  62. func (engine *Engine) SetTableMapper(mapper core.IMapper) {
  63. engine.TableMapper = mapper
  64. }
  65. func (engine *Engine) SetColumnMapper(mapper core.IMapper) {
  66. engine.ColumnMapper = mapper
  67. }
  68. // If engine's database support batch insert records like
  69. // "insert into user values (name, age), (name, age)".
  70. // When the return is ture, then engine.Insert(&users) will
  71. // generate batch sql and exeute.
  72. func (engine *Engine) SupportInsertMany() bool {
  73. return engine.dialect.SupportInsertMany()
  74. }
  75. // Engine's database use which charactor as quote.
  76. // mysql, sqlite use ` and postgres use "
  77. func (engine *Engine) QuoteStr() string {
  78. return engine.dialect.QuoteStr()
  79. }
  80. // Use QuoteStr quote the string sql
  81. func (engine *Engine) Quote(sql string) string {
  82. if len(sql) == 0 {
  83. return sql
  84. }
  85. if string(sql[0]) == engine.dialect.QuoteStr() || sql[0] == '`' {
  86. return sql
  87. }
  88. return engine.dialect.QuoteStr() + sql + engine.dialect.QuoteStr()
  89. }
  90. // A simple wrapper to dialect's core.SqlType method
  91. func (engine *Engine) SqlType(c *core.Column) string {
  92. return engine.dialect.SqlType(c)
  93. }
  94. // Database's autoincrement statement
  95. func (engine *Engine) AutoIncrStr() string {
  96. return engine.dialect.AutoIncrStr()
  97. }
  98. // SetMaxOpenConns is only available for go 1.2+
  99. func (engine *Engine) SetMaxOpenConns(conns int) {
  100. engine.db.SetMaxOpenConns(conns)
  101. }
  102. // @Deprecated
  103. func (engine *Engine) SetMaxConns(conns int) {
  104. engine.SetMaxOpenConns(conns)
  105. }
  106. // SetMaxIdleConns
  107. func (engine *Engine) SetMaxIdleConns(conns int) {
  108. engine.db.SetMaxIdleConns(conns)
  109. }
  110. // SetDefaltCacher set the default cacher. Xorm's default not enable cacher.
  111. func (engine *Engine) SetDefaultCacher(cacher core.Cacher) {
  112. engine.Cacher = cacher
  113. }
  114. // If you has set default cacher, and you want temporilly stop use cache,
  115. // you can use NoCache()
  116. func (engine *Engine) NoCache() *Session {
  117. session := engine.NewSession()
  118. session.IsAutoClose = true
  119. return session.NoCache()
  120. }
  121. func (engine *Engine) NoCascade() *Session {
  122. session := engine.NewSession()
  123. session.IsAutoClose = true
  124. return session.NoCascade()
  125. }
  126. // Set a table use a special cacher
  127. func (engine *Engine) MapCacher(bean interface{}, cacher core.Cacher) {
  128. v := rValue(bean)
  129. tb := engine.autoMapType(v)
  130. tb.Cacher = cacher
  131. }
  132. // NewDB provides an interface to operate database directly
  133. func (engine *Engine) NewDB() (*core.DB, error) {
  134. return core.OpenDialect(engine.dialect)
  135. }
  136. func (engine *Engine) DB() *core.DB {
  137. return engine.db
  138. }
  139. func (engine *Engine) Dialect() core.Dialect {
  140. return engine.dialect
  141. }
  142. // New a session
  143. func (engine *Engine) NewSession() *Session {
  144. session := &Session{Engine: engine}
  145. session.Init()
  146. return session
  147. }
  148. // Close the engine
  149. func (engine *Engine) Close() error {
  150. return engine.db.Close()
  151. }
  152. // Ping tests if database is alive
  153. func (engine *Engine) Ping() error {
  154. session := engine.NewSession()
  155. defer session.Close()
  156. engine.LogInfo("PING DATABASE", engine.DriverName)
  157. return session.Ping()
  158. }
  159. // logging sql
  160. func (engine *Engine) logSQL(sqlStr string, sqlArgs ...interface{}) {
  161. if engine.ShowSQL {
  162. engine.overrideLogLevel(core.LOG_INFO)
  163. if len(sqlArgs) > 0 {
  164. engine.Logger.Infof("[sql] %v [args] %v", sqlStr, sqlArgs)
  165. } else {
  166. engine.Logger.Infof("[sql] %v", sqlStr)
  167. }
  168. }
  169. }
  170. func (engine *Engine) LogSQLQueryTime(sqlStr string, args interface{}, executionBlock func() (*core.Stmt, *core.Rows, error)) (*core.Stmt, *core.Rows, error) {
  171. if engine.ShowDebug {
  172. b4ExecTime := time.Now()
  173. stmt, res, err := executionBlock()
  174. execDuration := time.Since(b4ExecTime)
  175. engine.LogDebugf("[time] %s - args %v - query took: %vns", sqlStr, args, execDuration.Nanoseconds())
  176. return stmt, res, err
  177. } else {
  178. return executionBlock()
  179. }
  180. }
  181. func (engine *Engine) LogSQLExecutionTime(sqlStr string, args interface{}, executionBlock func() (sql.Result, error)) (sql.Result, error) {
  182. if engine.ShowDebug {
  183. b4ExecTime := time.Now()
  184. res, err := executionBlock()
  185. execDuration := time.Since(b4ExecTime)
  186. engine.LogDebugf("[time] %s - args %v - execution took: %vns", sqlStr, args, execDuration.Nanoseconds())
  187. return res, err
  188. } else {
  189. return executionBlock()
  190. }
  191. }
  192. // logging error
  193. func (engine *Engine) overrideLogLevel(overrideLevel core.LogLevel) {
  194. logLevel := engine.Logger.Level()
  195. if logLevel == core.LOG_UNKNOWN {
  196. // intend to left empty
  197. } else if logLevel < overrideLevel { // TODO can remove if deprecated engine.ShowErr
  198. engine.Logger.SetLevel(core.LOG_ERR) // try override logger's log level
  199. }
  200. }
  201. func (engine *Engine) LogError(contents ...interface{}) {
  202. if engine.ShowErr {
  203. engine.overrideLogLevel(core.LOG_ERR)
  204. engine.Logger.Err(contents...)
  205. }
  206. }
  207. func (engine *Engine) LogErrorf(format string, contents ...interface{}) {
  208. if engine.ShowErr {
  209. engine.overrideLogLevel(core.LOG_ERR)
  210. engine.Logger.Errf(format, contents...)
  211. }
  212. }
  213. // logging info
  214. func (engine *Engine) LogInfo(contents ...interface{}) {
  215. if engine.ShowInfo {
  216. engine.overrideLogLevel(core.LOG_INFO)
  217. engine.Logger.Info(contents...)
  218. }
  219. }
  220. func (engine *Engine) LogInfof(format string, contents ...interface{}) {
  221. if engine.ShowErr {
  222. engine.overrideLogLevel(core.LOG_INFO)
  223. engine.Logger.Infof(format, contents...)
  224. }
  225. }
  226. // logging debug
  227. func (engine *Engine) LogDebug(contents ...interface{}) {
  228. if engine.ShowDebug {
  229. engine.overrideLogLevel(core.LOG_DEBUG)
  230. engine.Logger.Debug(contents...)
  231. }
  232. }
  233. func (engine *Engine) LogDebugf(format string, contents ...interface{}) {
  234. if engine.ShowDebug {
  235. engine.overrideLogLevel(core.LOG_DEBUG)
  236. engine.Logger.Debugf(format, contents...)
  237. }
  238. }
  239. // logging warn
  240. func (engine *Engine) LogWarn(contents ...interface{}) {
  241. if engine.ShowWarn {
  242. engine.overrideLogLevel(core.LOG_WARNING)
  243. engine.Logger.Warning(contents...)
  244. }
  245. }
  246. func (engine *Engine) LogWarnf(format string, contents ...interface{}) {
  247. if engine.ShowWarn {
  248. engine.overrideLogLevel(core.LOG_WARNING)
  249. engine.Logger.Warningf(format, contents...)
  250. }
  251. }
  252. // Sql method let's you manualy write raw sql and operate
  253. // For example:
  254. //
  255. // engine.Sql("select * from user").Find(&users)
  256. //
  257. // This code will execute "select * from user" and set the records to users
  258. //
  259. func (engine *Engine) Sql(querystring string, args ...interface{}) *Session {
  260. session := engine.NewSession()
  261. session.IsAutoClose = true
  262. return session.Sql(querystring, args...)
  263. }
  264. // Default if your struct has "created" or "updated" filed tag, the fields
  265. // will automatically be filled with current time when Insert or Update
  266. // invoked. Call NoAutoTime if you dont' want to fill automatically.
  267. func (engine *Engine) NoAutoTime() *Session {
  268. session := engine.NewSession()
  269. session.IsAutoClose = true
  270. return session.NoAutoTime()
  271. }
  272. // Retrieve all tables, columns, indexes' informations from database.
  273. func (engine *Engine) DBMetas() ([]*core.Table, error) {
  274. tables, err := engine.dialect.GetTables()
  275. if err != nil {
  276. return nil, err
  277. }
  278. for _, table := range tables {
  279. colSeq, cols, err := engine.dialect.GetColumns(table.Name)
  280. if err != nil {
  281. return nil, err
  282. }
  283. for _, name := range colSeq {
  284. table.AddColumn(cols[name])
  285. }
  286. //table.Columns = cols
  287. //table.ColumnsSeq = colSeq
  288. indexes, err := engine.dialect.GetIndexes(table.Name)
  289. if err != nil {
  290. return nil, err
  291. }
  292. table.Indexes = indexes
  293. for _, index := range indexes {
  294. for _, name := range index.Cols {
  295. if col := table.GetColumn(name); col != nil {
  296. col.Indexes[index.Name] = true
  297. } else {
  298. return nil, fmt.Errorf("Unknown col "+name+" in indexes %v of table", index, table.ColumnsSeq())
  299. }
  300. }
  301. }
  302. }
  303. return tables, nil
  304. }
  305. /*
  306. dump database all table structs and data to a file
  307. */
  308. func (engine *Engine) DumpAllToFile(fp string) error {
  309. f, err := os.Create(fp)
  310. if err != nil {
  311. return err
  312. }
  313. defer f.Close()
  314. return engine.DumpAll(f)
  315. }
  316. /*
  317. dump database all table structs and data to w
  318. */
  319. func (engine *Engine) DumpAll(w io.Writer) error {
  320. tables, err := engine.DBMetas()
  321. if err != nil {
  322. return err
  323. }
  324. for _, table := range tables {
  325. _, err = io.WriteString(w, engine.dialect.CreateTableSql(table, "", table.StoreEngine, "")+"\n\n")
  326. if err != nil {
  327. return err
  328. }
  329. for _, index := range table.Indexes {
  330. _, err = io.WriteString(w, engine.dialect.CreateIndexSql(table.Name, index)+"\n\n")
  331. if err != nil {
  332. return err
  333. }
  334. }
  335. rows, err := engine.DB().Query("SELECT * FROM " + engine.Quote(table.Name))
  336. if err != nil {
  337. return err
  338. }
  339. cols, err := rows.Columns()
  340. if err != nil {
  341. return err
  342. }
  343. if len(cols) == 0 {
  344. continue
  345. }
  346. for rows.Next() {
  347. dest := make([]interface{}, len(cols))
  348. err = rows.ScanSlice(&dest)
  349. if err != nil {
  350. return err
  351. }
  352. _, err = io.WriteString(w, "INSERT INTO "+engine.Quote(table.Name)+" ("+engine.Quote(strings.Join(cols, engine.Quote(", ")))+") VALUES (")
  353. if err != nil {
  354. return err
  355. }
  356. var temp string
  357. for i, d := range dest {
  358. col := table.GetColumn(cols[i])
  359. if d == nil {
  360. temp += ", NULL"
  361. } else if col.SQLType.IsText() || col.SQLType.IsTime() {
  362. var v = fmt.Sprintf("%s", d)
  363. temp += ", '" + strings.Replace(v, "'", "''", -1) + "'"
  364. } else if col.SQLType.IsBlob() {
  365. if reflect.TypeOf(d).Kind() == reflect.Slice {
  366. temp += fmt.Sprintf(", %s", engine.dialect.FormatBytes(d.([]byte)))
  367. } else if reflect.TypeOf(d).Kind() == reflect.String {
  368. temp += fmt.Sprintf(", '%s'", d.(string))
  369. }
  370. } else if col.SQLType.IsNumeric() {
  371. switch reflect.TypeOf(d).Kind() {
  372. case reflect.Slice:
  373. temp += fmt.Sprintf(", %s", string(d.([]byte)))
  374. default:
  375. temp += fmt.Sprintf(", %v", d)
  376. }
  377. } else {
  378. s := fmt.Sprintf("%v", d)
  379. if strings.Contains(s, ":") || strings.Contains(s, "-") {
  380. temp += fmt.Sprintf(", '%s'", s)
  381. } else {
  382. temp += fmt.Sprintf(", %s", s)
  383. }
  384. }
  385. }
  386. _, err = io.WriteString(w, temp[2:]+");\n\n")
  387. if err != nil {
  388. return err
  389. }
  390. }
  391. }
  392. return nil
  393. }
  394. // use cascade or not
  395. func (engine *Engine) Cascade(trueOrFalse ...bool) *Session {
  396. session := engine.NewSession()
  397. session.IsAutoClose = true
  398. return session.Cascade(trueOrFalse...)
  399. }
  400. // Where method provide a condition query
  401. func (engine *Engine) Where(querystring string, args ...interface{}) *Session {
  402. session := engine.NewSession()
  403. session.IsAutoClose = true
  404. return session.Where(querystring, args...)
  405. }
  406. // Id mehtod provoide a condition as (id) = ?
  407. func (engine *Engine) Id(id interface{}) *Session {
  408. session := engine.NewSession()
  409. session.IsAutoClose = true
  410. return session.Id(id)
  411. }
  412. // Apply before Processor, affected bean is passed to closure arg
  413. func (engine *Engine) Before(closures func(interface{})) *Session {
  414. session := engine.NewSession()
  415. session.IsAutoClose = true
  416. return session.Before(closures)
  417. }
  418. // Apply after insert Processor, affected bean is passed to closure arg
  419. func (engine *Engine) After(closures func(interface{})) *Session {
  420. session := engine.NewSession()
  421. session.IsAutoClose = true
  422. return session.After(closures)
  423. }
  424. // set charset when create table, only support mysql now
  425. func (engine *Engine) Charset(charset string) *Session {
  426. session := engine.NewSession()
  427. session.IsAutoClose = true
  428. return session.Charset(charset)
  429. }
  430. // set store engine when create table, only support mysql now
  431. func (engine *Engine) StoreEngine(storeEngine string) *Session {
  432. session := engine.NewSession()
  433. session.IsAutoClose = true
  434. return session.StoreEngine(storeEngine)
  435. }
  436. // use for distinct columns. Caution: when you are using cache,
  437. // distinct will not be cached because cache system need id,
  438. // but distinct will not provide id
  439. func (engine *Engine) Distinct(columns ...string) *Session {
  440. session := engine.NewSession()
  441. session.IsAutoClose = true
  442. return session.Distinct(columns...)
  443. }
  444. func (engine *Engine) Select(str string) *Session {
  445. session := engine.NewSession()
  446. session.IsAutoClose = true
  447. return session.Select(str)
  448. }
  449. // only use the paramters as select or update columns
  450. func (engine *Engine) Cols(columns ...string) *Session {
  451. session := engine.NewSession()
  452. session.IsAutoClose = true
  453. return session.Cols(columns...)
  454. }
  455. func (engine *Engine) AllCols() *Session {
  456. session := engine.NewSession()
  457. session.IsAutoClose = true
  458. return session.AllCols()
  459. }
  460. func (engine *Engine) MustCols(columns ...string) *Session {
  461. session := engine.NewSession()
  462. session.IsAutoClose = true
  463. return session.MustCols(columns...)
  464. }
  465. // Xorm automatically retrieve condition according struct, but
  466. // if struct has bool field, it will ignore them. So use UseBool
  467. // to tell system to do not ignore them.
  468. // If no paramters, it will use all the bool field of struct, or
  469. // it will use paramters's columns
  470. func (engine *Engine) UseBool(columns ...string) *Session {
  471. session := engine.NewSession()
  472. session.IsAutoClose = true
  473. return session.UseBool(columns...)
  474. }
  475. // Only not use the paramters as select or update columns
  476. func (engine *Engine) Omit(columns ...string) *Session {
  477. session := engine.NewSession()
  478. session.IsAutoClose = true
  479. return session.Omit(columns...)
  480. }
  481. // This method will generate "column IN (?, ?)"
  482. func (engine *Engine) In(column string, args ...interface{}) *Session {
  483. session := engine.NewSession()
  484. session.IsAutoClose = true
  485. return session.In(column, args...)
  486. }
  487. // Method Inc provides a update string like "column = column + ?"
  488. func (engine *Engine) Incr(column string, arg ...interface{}) *Session {
  489. session := engine.NewSession()
  490. session.IsAutoClose = true
  491. return session.Incr(column, arg...)
  492. }
  493. // Method Decr provides a update string like "column = column - ?"
  494. func (engine *Engine) Decr(column string, arg ...interface{}) *Session {
  495. session := engine.NewSession()
  496. session.IsAutoClose = true
  497. return session.Decr(column, arg...)
  498. }
  499. // Method SetExpr provides a update string like "column = {expression}"
  500. func (engine *Engine) SetExpr(column string, expression string) *Session {
  501. session := engine.NewSession()
  502. session.IsAutoClose = true
  503. return session.SetExpr(column, expression)
  504. }
  505. // Temporarily change the Get, Find, Update's table
  506. func (engine *Engine) Table(tableNameOrBean interface{}) *Session {
  507. session := engine.NewSession()
  508. session.IsAutoClose = true
  509. return session.Table(tableNameOrBean)
  510. }
  511. // set the table alias
  512. func (engine *Engine) Alias(alias string) *Session {
  513. session := engine.NewSession()
  514. session.IsAutoClose = true
  515. return session.Alias(alias)
  516. }
  517. // This method will generate "LIMIT start, limit"
  518. func (engine *Engine) Limit(limit int, start ...int) *Session {
  519. session := engine.NewSession()
  520. session.IsAutoClose = true
  521. return session.Limit(limit, start...)
  522. }
  523. // Method Desc will generate "ORDER BY column1 DESC, column2 DESC"
  524. // This will
  525. func (engine *Engine) Desc(colNames ...string) *Session {
  526. session := engine.NewSession()
  527. session.IsAutoClose = true
  528. return session.Desc(colNames...)
  529. }
  530. // Method Asc will generate "ORDER BY column1,column2 Asc"
  531. // This method can chainable use.
  532. //
  533. // engine.Desc("name").Asc("age").Find(&users)
  534. // // SELECT * FROM user ORDER BY name DESC, age ASC
  535. //
  536. func (engine *Engine) Asc(colNames ...string) *Session {
  537. session := engine.NewSession()
  538. session.IsAutoClose = true
  539. return session.Asc(colNames...)
  540. }
  541. // Method OrderBy will generate "ORDER BY order"
  542. func (engine *Engine) OrderBy(order string) *Session {
  543. session := engine.NewSession()
  544. session.IsAutoClose = true
  545. return session.OrderBy(order)
  546. }
  547. // The join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN
  548. func (engine *Engine) Join(join_operator string, tablename interface{}, condition string) *Session {
  549. session := engine.NewSession()
  550. session.IsAutoClose = true
  551. return session.Join(join_operator, tablename, condition)
  552. }
  553. // Generate Group By statement
  554. func (engine *Engine) GroupBy(keys string) *Session {
  555. session := engine.NewSession()
  556. session.IsAutoClose = true
  557. return session.GroupBy(keys)
  558. }
  559. // Generate Having statement
  560. func (engine *Engine) Having(conditions string) *Session {
  561. session := engine.NewSession()
  562. session.IsAutoClose = true
  563. return session.Having(conditions)
  564. }
  565. func (engine *Engine) autoMapType(v reflect.Value) *core.Table {
  566. t := v.Type()
  567. engine.mutex.Lock()
  568. table, ok := engine.Tables[t]
  569. if !ok {
  570. table = engine.mapType(v)
  571. engine.Tables[t] = table
  572. if v.CanAddr() {
  573. engine.GobRegister(v.Addr().Interface())
  574. } else {
  575. engine.GobRegister(v.Interface())
  576. }
  577. }
  578. engine.mutex.Unlock()
  579. return table
  580. }
  581. func (engine *Engine) GobRegister(v interface{}) *Engine {
  582. //fmt.Printf("Type: %[1]T => Data: %[1]#v\n", v)
  583. gob.Register(v)
  584. return engine
  585. }
  586. func (engine *Engine) TableInfo(bean interface{}) *core.Table {
  587. v := rValue(bean)
  588. return engine.autoMapType(v)
  589. }
  590. func addIndex(indexName string, table *core.Table, col *core.Column, indexType int) {
  591. if index, ok := table.Indexes[indexName]; ok {
  592. index.AddColumn(col.Name)
  593. col.Indexes[index.Name] = true
  594. } else {
  595. index := core.NewIndex(indexName, indexType)
  596. index.AddColumn(col.Name)
  597. table.AddIndex(index)
  598. col.Indexes[index.Name] = true
  599. }
  600. }
  601. func (engine *Engine) newTable() *core.Table {
  602. table := core.NewEmptyTable()
  603. if !engine.disableGlobalCache {
  604. table.Cacher = engine.Cacher
  605. }
  606. return table
  607. }
  608. func (engine *Engine) mapType(v reflect.Value) *core.Table {
  609. t := v.Type()
  610. table := engine.newTable()
  611. method := v.MethodByName("TableName")
  612. if !method.IsValid() {
  613. if v.CanAddr() {
  614. method = v.Addr().MethodByName("TableName")
  615. }
  616. }
  617. if method.IsValid() {
  618. params := []reflect.Value{}
  619. results := method.Call(params)
  620. if len(results) == 1 {
  621. table.Name = results[0].Interface().(string)
  622. }
  623. }
  624. if table.Name == "" {
  625. table.Name = engine.TableMapper.Obj2Table(t.Name())
  626. }
  627. table.Type = t
  628. var idFieldColName string
  629. var err error
  630. hasCacheTag := false
  631. hasNoCacheTag := false
  632. for i := 0; i < t.NumField(); i++ {
  633. tag := t.Field(i).Tag
  634. ormTagStr := tag.Get(engine.TagIdentifier)
  635. var col *core.Column
  636. fieldValue := v.Field(i)
  637. fieldType := fieldValue.Type()
  638. if ormTagStr != "" {
  639. col = &core.Column{FieldName: t.Field(i).Name, Nullable: true, IsPrimaryKey: false,
  640. IsAutoIncrement: false, MapType: core.TWOSIDES, Indexes: make(map[string]bool)}
  641. tags := strings.Split(ormTagStr, " ")
  642. if len(tags) > 0 {
  643. if tags[0] == "-" {
  644. continue
  645. }
  646. if strings.ToUpper(tags[0]) == "EXTENDS" {
  647. if fieldValue.Kind() == reflect.Struct {
  648. parentTable := engine.mapType(fieldValue)
  649. for _, col := range parentTable.Columns() {
  650. col.FieldName = fmt.Sprintf("%v.%v", t.Field(i).Name, col.FieldName)
  651. table.AddColumn(col)
  652. }
  653. continue
  654. } else if fieldValue.Kind() == reflect.Ptr {
  655. f := fieldValue.Type().Elem()
  656. if f.Kind() == reflect.Struct {
  657. fieldValue = fieldValue.Elem()
  658. if !fieldValue.IsValid() || fieldValue.IsNil() {
  659. fieldValue = reflect.New(f).Elem()
  660. }
  661. }
  662. parentTable := engine.mapType(fieldValue)
  663. for _, col := range parentTable.Columns() {
  664. col.FieldName = fmt.Sprintf("%v.%v", t.Field(i).Name, col.FieldName)
  665. table.AddColumn(col)
  666. }
  667. continue
  668. }
  669. //TODO: warning
  670. }
  671. indexNames := make(map[string]int)
  672. var isIndex, isUnique bool
  673. var preKey string
  674. for j, key := range tags {
  675. k := strings.ToUpper(key)
  676. switch {
  677. case k == "<-":
  678. col.MapType = core.ONLYFROMDB
  679. case k == "->":
  680. col.MapType = core.ONLYTODB
  681. case k == "PK":
  682. col.IsPrimaryKey = true
  683. col.Nullable = false
  684. case k == "NULL":
  685. if j == 0 {
  686. col.Nullable = true
  687. } else {
  688. col.Nullable = (strings.ToUpper(tags[j-1]) != "NOT")
  689. }
  690. // TODO: for postgres how add autoincr?
  691. /*case strings.HasPrefix(k, "AUTOINCR(") && strings.HasSuffix(k, ")"):
  692. col.IsAutoIncrement = true
  693. autoStart := k[len("AUTOINCR")+1 : len(k)-1]
  694. autoStartInt, err := strconv.Atoi(autoStart)
  695. if err != nil {
  696. engine.LogError(err)
  697. }
  698. col.AutoIncrStart = autoStartInt*/
  699. case k == "AUTOINCR":
  700. col.IsAutoIncrement = true
  701. //col.AutoIncrStart = 1
  702. case k == "DEFAULT":
  703. col.Default = tags[j+1]
  704. case k == "CREATED":
  705. col.IsCreated = true
  706. case k == "VERSION":
  707. col.IsVersion = true
  708. col.Default = "1"
  709. case k == "UPDATED":
  710. col.IsUpdated = true
  711. case k == "DELETED":
  712. col.IsDeleted = true
  713. case strings.HasPrefix(k, "INDEX(") && strings.HasSuffix(k, ")"):
  714. indexName := k[len("INDEX")+1 : len(k)-1]
  715. indexNames[indexName] = core.IndexType
  716. case k == "INDEX":
  717. isIndex = true
  718. case strings.HasPrefix(k, "UNIQUE(") && strings.HasSuffix(k, ")"):
  719. indexName := k[len("UNIQUE")+1 : len(k)-1]
  720. indexNames[indexName] = core.UniqueType
  721. case k == "UNIQUE":
  722. isUnique = true
  723. case k == "NOTNULL":
  724. col.Nullable = false
  725. case k == "CACHE":
  726. if !hasCacheTag {
  727. hasCacheTag = true
  728. }
  729. case k == "NOCACHE":
  730. if !hasNoCacheTag {
  731. hasNoCacheTag = true
  732. }
  733. case k == "NOT":
  734. default:
  735. if strings.HasPrefix(k, "'") && strings.HasSuffix(k, "'") {
  736. if preKey != "DEFAULT" {
  737. col.Name = key[1 : len(key)-1]
  738. }
  739. } else if strings.Contains(k, "(") && strings.HasSuffix(k, ")") {
  740. fs := strings.Split(k, "(")
  741. if _, ok := core.SqlTypes[fs[0]]; !ok {
  742. preKey = k
  743. continue
  744. }
  745. col.SQLType = core.SQLType{fs[0], 0, 0}
  746. if fs[0] == core.Enum && fs[1][0] == '\'' { //enum
  747. options := strings.Split(fs[1][0:len(fs[1])-1], ",")
  748. col.EnumOptions = make(map[string]int)
  749. for k, v := range options {
  750. v = strings.TrimSpace(v)
  751. v = strings.Trim(v, "'")
  752. col.EnumOptions[v] = k
  753. }
  754. } else if fs[0] == core.Set && fs[1][0] == '\'' { //set
  755. options := strings.Split(fs[1][0:len(fs[1])-1], ",")
  756. col.SetOptions = make(map[string]int)
  757. for k, v := range options {
  758. v = strings.TrimSpace(v)
  759. v = strings.Trim(v, "'")
  760. col.SetOptions[v] = k
  761. }
  762. } else {
  763. fs2 := strings.Split(fs[1][0:len(fs[1])-1], ",")
  764. if len(fs2) == 2 {
  765. col.Length, err = strconv.Atoi(fs2[0])
  766. if err != nil {
  767. engine.LogError(err)
  768. }
  769. col.Length2, err = strconv.Atoi(fs2[1])
  770. if err != nil {
  771. engine.LogError(err)
  772. }
  773. } else if len(fs2) == 1 {
  774. col.Length, err = strconv.Atoi(fs2[0])
  775. if err != nil {
  776. engine.LogError(err)
  777. }
  778. }
  779. }
  780. } else {
  781. if _, ok := core.SqlTypes[k]; ok {
  782. col.SQLType = core.SQLType{k, 0, 0}
  783. } else if key != col.Default {
  784. col.Name = key
  785. }
  786. }
  787. engine.dialect.SqlType(col)
  788. }
  789. preKey = k
  790. }
  791. if col.SQLType.Name == "" {
  792. col.SQLType = core.Type2SQLType(fieldType)
  793. }
  794. if col.Length == 0 {
  795. col.Length = col.SQLType.DefaultLength
  796. }
  797. if col.Length2 == 0 {
  798. col.Length2 = col.SQLType.DefaultLength2
  799. }
  800. if col.Name == "" {
  801. col.Name = engine.ColumnMapper.Obj2Table(t.Field(i).Name)
  802. }
  803. if isUnique {
  804. indexNames[col.Name] = core.UniqueType
  805. } else if isIndex {
  806. indexNames[col.Name] = core.IndexType
  807. }
  808. for indexName, indexType := range indexNames {
  809. addIndex(indexName, table, col, indexType)
  810. }
  811. }
  812. } else {
  813. var sqlType core.SQLType
  814. if fieldValue.CanAddr() {
  815. if _, ok := fieldValue.Addr().Interface().(core.Conversion); ok {
  816. sqlType = core.SQLType{core.Text, 0, 0}
  817. }
  818. }
  819. if _, ok := fieldValue.Interface().(core.Conversion); ok {
  820. sqlType = core.SQLType{core.Text, 0, 0}
  821. } else {
  822. sqlType = core.Type2SQLType(fieldType)
  823. }
  824. col = core.NewColumn(engine.ColumnMapper.Obj2Table(t.Field(i).Name),
  825. t.Field(i).Name, sqlType, sqlType.DefaultLength,
  826. sqlType.DefaultLength2, true)
  827. }
  828. if col.IsAutoIncrement {
  829. col.Nullable = false
  830. }
  831. table.AddColumn(col)
  832. if fieldType.Kind() == reflect.Int64 && (strings.ToUpper(col.FieldName) == "ID" || strings.HasSuffix(strings.ToUpper(col.FieldName), ".ID")) {
  833. idFieldColName = col.Name
  834. }
  835. } // end for
  836. if idFieldColName != "" && len(table.PrimaryKeys) == 0 {
  837. col := table.GetColumn(idFieldColName)
  838. col.IsPrimaryKey = true
  839. col.IsAutoIncrement = true
  840. col.Nullable = false
  841. table.PrimaryKeys = append(table.PrimaryKeys, col.Name)
  842. table.AutoIncrement = col.Name
  843. }
  844. if hasCacheTag {
  845. if engine.Cacher != nil { // !nash! use engine's cacher if provided
  846. engine.Logger.Info("enable cache on table:", table.Name)
  847. table.Cacher = engine.Cacher
  848. } else {
  849. engine.Logger.Info("enable LRU cache on table:", table.Name)
  850. table.Cacher = NewLRUCacher2(NewMemoryStore(), time.Hour, 10000) // !nashtsai! HACK use LRU cacher for now
  851. }
  852. }
  853. if hasNoCacheTag {
  854. engine.Logger.Info("no cache on table:", table.Name)
  855. table.Cacher = nil
  856. }
  857. return table
  858. }
  859. // Map a struct to a table
  860. func (engine *Engine) mapping(beans ...interface{}) (e error) {
  861. engine.mutex.Lock()
  862. defer engine.mutex.Unlock()
  863. for _, bean := range beans {
  864. v := rValue(bean)
  865. engine.Tables[v.Type()] = engine.mapType(v)
  866. }
  867. return
  868. }
  869. // If a table has any reocrd
  870. func (engine *Engine) IsTableEmpty(bean interface{}) (bool, error) {
  871. session := engine.NewSession()
  872. defer session.Close()
  873. return session.IsTableEmpty(bean)
  874. }
  875. // If a table is exist
  876. func (engine *Engine) IsTableExist(beanOrTableName interface{}) (bool, error) {
  877. session := engine.NewSession()
  878. defer session.Close()
  879. return session.IsTableExist(beanOrTableName)
  880. }
  881. func (engine *Engine) IdOf(bean interface{}) core.PK {
  882. return engine.IdOfV(reflect.ValueOf(bean))
  883. }
  884. func (engine *Engine) IdOfV(rv reflect.Value) core.PK {
  885. v := reflect.Indirect(rv)
  886. table := engine.autoMapType(v)
  887. pk := make([]interface{}, len(table.PrimaryKeys))
  888. for i, col := range table.PKColumns() {
  889. pkField := v.FieldByName(col.FieldName)
  890. switch pkField.Kind() {
  891. case reflect.String:
  892. pk[i] = pkField.String()
  893. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  894. pk[i] = pkField.Int()
  895. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  896. pk[i] = pkField.Uint()
  897. }
  898. }
  899. return core.PK(pk)
  900. }
  901. // create indexes
  902. func (engine *Engine) CreateIndexes(bean interface{}) error {
  903. session := engine.NewSession()
  904. defer session.Close()
  905. return session.CreateIndexes(bean)
  906. }
  907. // create uniques
  908. func (engine *Engine) CreateUniques(bean interface{}) error {
  909. session := engine.NewSession()
  910. defer session.Close()
  911. return session.CreateUniques(bean)
  912. }
  913. func (engine *Engine) getCacher2(table *core.Table) core.Cacher {
  914. return table.Cacher
  915. }
  916. func (engine *Engine) getCacher(v reflect.Value) core.Cacher {
  917. if table := engine.autoMapType(v); table != nil {
  918. return table.Cacher
  919. }
  920. return engine.Cacher
  921. }
  922. // If enabled cache, clear the cache bean
  923. func (engine *Engine) ClearCacheBean(bean interface{}, id string) error {
  924. t := rType(bean)
  925. if t.Kind() != reflect.Struct {
  926. return errors.New("error params")
  927. }
  928. table := engine.TableInfo(bean)
  929. cacher := table.Cacher
  930. if cacher == nil {
  931. cacher = engine.Cacher
  932. }
  933. if cacher != nil {
  934. cacher.ClearIds(table.Name)
  935. cacher.DelBean(table.Name, id)
  936. }
  937. return nil
  938. }
  939. // If enabled cache, clear some tables' cache
  940. func (engine *Engine) ClearCache(beans ...interface{}) error {
  941. for _, bean := range beans {
  942. t := rType(bean)
  943. if t.Kind() != reflect.Struct {
  944. return errors.New("error params")
  945. }
  946. table := engine.TableInfo(bean)
  947. cacher := table.Cacher
  948. if cacher == nil {
  949. cacher = engine.Cacher
  950. }
  951. if cacher != nil {
  952. cacher.ClearIds(table.Name)
  953. cacher.ClearBeans(table.Name)
  954. }
  955. }
  956. return nil
  957. }
  958. // Sync the new struct changes to database, this method will automatically add
  959. // table, column, index, unique. but will not delete or change anything.
  960. // If you change some field, you should change the database manually.
  961. func (engine *Engine) Sync(beans ...interface{}) error {
  962. for _, bean := range beans {
  963. table := engine.TableInfo(bean)
  964. s := engine.NewSession()
  965. defer s.Close()
  966. isExist, err := s.Table(bean).isTableExist(table.Name)
  967. if err != nil {
  968. return err
  969. }
  970. if !isExist {
  971. err = engine.CreateTables(bean)
  972. if err != nil {
  973. return err
  974. }
  975. }
  976. /*isEmpty, err := engine.IsEmptyTable(bean)
  977. if err != nil {
  978. return err
  979. }*/
  980. var isEmpty bool = false
  981. if isEmpty {
  982. err = engine.DropTables(bean)
  983. if err != nil {
  984. return err
  985. }
  986. err = engine.CreateTables(bean)
  987. if err != nil {
  988. return err
  989. }
  990. } else {
  991. for _, col := range table.Columns() {
  992. session := engine.NewSession()
  993. session.Statement.RefTable = table
  994. defer session.Close()
  995. isExist, err := session.Engine.dialect.IsColumnExist(table.Name, col.Name)
  996. if err != nil {
  997. return err
  998. }
  999. if !isExist {
  1000. session := engine.NewSession()
  1001. session.Statement.RefTable = table
  1002. defer session.Close()
  1003. err = session.addColumn(col.Name)
  1004. if err != nil {
  1005. return err
  1006. }
  1007. }
  1008. }
  1009. for name, index := range table.Indexes {
  1010. session := engine.NewSession()
  1011. session.Statement.RefTable = table
  1012. defer session.Close()
  1013. if index.Type == core.UniqueType {
  1014. //isExist, err := session.isIndexExist(table.Name, name, true)
  1015. isExist, err := session.isIndexExist2(table.Name, index.Cols, true)
  1016. if err != nil {
  1017. return err
  1018. }
  1019. if !isExist {
  1020. session := engine.NewSession()
  1021. session.Statement.RefTable = table
  1022. defer session.Close()
  1023. err = session.addUnique(table.Name, name)
  1024. if err != nil {
  1025. return err
  1026. }
  1027. }
  1028. } else if index.Type == core.IndexType {
  1029. isExist, err := session.isIndexExist2(table.Name, index.Cols, false)
  1030. if err != nil {
  1031. return err
  1032. }
  1033. if !isExist {
  1034. session := engine.NewSession()
  1035. session.Statement.RefTable = table
  1036. defer session.Close()
  1037. err = session.addIndex(table.Name, name)
  1038. if err != nil {
  1039. return err
  1040. }
  1041. }
  1042. } else {
  1043. return errors.New("unknow index type")
  1044. }
  1045. }
  1046. }
  1047. }
  1048. return nil
  1049. }
  1050. func (engine *Engine) Sync2(beans ...interface{}) error {
  1051. s := engine.NewSession()
  1052. defer s.Close()
  1053. return s.Sync2(beans...)
  1054. }
  1055. func (engine *Engine) unMap(beans ...interface{}) (e error) {
  1056. engine.mutex.Lock()
  1057. defer engine.mutex.Unlock()
  1058. for _, bean := range beans {
  1059. t := rType(bean)
  1060. if _, ok := engine.Tables[t]; ok {
  1061. delete(engine.Tables, t)
  1062. }
  1063. }
  1064. return
  1065. }
  1066. // Drop all mapped table
  1067. func (engine *Engine) dropAll() error {
  1068. session := engine.NewSession()
  1069. defer session.Close()
  1070. err := session.Begin()
  1071. if err != nil {
  1072. return err
  1073. }
  1074. err = session.dropAll()
  1075. if err != nil {
  1076. session.Rollback()
  1077. return err
  1078. }
  1079. return session.Commit()
  1080. }
  1081. // CreateTables create tabls according bean
  1082. func (engine *Engine) CreateTables(beans ...interface{}) error {
  1083. session := engine.NewSession()
  1084. err := session.Begin()
  1085. defer session.Close()
  1086. if err != nil {
  1087. return err
  1088. }
  1089. for _, bean := range beans {
  1090. err = session.CreateTable(bean)
  1091. if err != nil {
  1092. session.Rollback()
  1093. return err
  1094. }
  1095. }
  1096. return session.Commit()
  1097. }
  1098. func (engine *Engine) DropTables(beans ...interface{}) error {
  1099. session := engine.NewSession()
  1100. defer session.Close()
  1101. err := session.Begin()
  1102. if err != nil {
  1103. return err
  1104. }
  1105. for _, bean := range beans {
  1106. err = session.DropTable(bean)
  1107. if err != nil {
  1108. session.Rollback()
  1109. return err
  1110. }
  1111. }
  1112. return session.Commit()
  1113. }
  1114. func (engine *Engine) createAll() error {
  1115. session := engine.NewSession()
  1116. defer session.Close()
  1117. return session.createAll()
  1118. }
  1119. // Exec raw sql
  1120. func (engine *Engine) Exec(sql string, args ...interface{}) (sql.Result, error) {
  1121. session := engine.NewSession()
  1122. defer session.Close()
  1123. return session.Exec(sql, args...)
  1124. }
  1125. // Exec a raw sql and return records as []map[string][]byte
  1126. func (engine *Engine) Query(sql string, paramStr ...interface{}) (resultsSlice []map[string][]byte, err error) {
  1127. session := engine.NewSession()
  1128. defer session.Close()
  1129. return session.Query(sql, paramStr...)
  1130. }
  1131. // Insert one or more records
  1132. func (engine *Engine) Insert(beans ...interface{}) (int64, error) {
  1133. session := engine.NewSession()
  1134. defer session.Close()
  1135. return session.Insert(beans...)
  1136. }
  1137. // Insert only one record
  1138. func (engine *Engine) InsertOne(bean interface{}) (int64, error) {
  1139. session := engine.NewSession()
  1140. defer session.Close()
  1141. return session.InsertOne(bean)
  1142. }
  1143. // Update records, bean's non-empty fields are updated contents,
  1144. // condiBean' non-empty filds are conditions
  1145. // CAUTION:
  1146. // 1.bool will defaultly be updated content nor conditions
  1147. // You should call UseBool if you have bool to use.
  1148. // 2.float32 & float64 may be not inexact as conditions
  1149. func (engine *Engine) Update(bean interface{}, condiBeans ...interface{}) (int64, error) {
  1150. session := engine.NewSession()
  1151. defer session.Close()
  1152. return session.Update(bean, condiBeans...)
  1153. }
  1154. // Delete records, bean's non-empty fields are conditions
  1155. func (engine *Engine) Delete(bean interface{}) (int64, error) {
  1156. session := engine.NewSession()
  1157. defer session.Close()
  1158. return session.Delete(bean)
  1159. }
  1160. // Get retrieve one record from table, bean's non-empty fields
  1161. // are conditions
  1162. func (engine *Engine) Get(bean interface{}) (bool, error) {
  1163. session := engine.NewSession()
  1164. defer session.Close()
  1165. return session.Get(bean)
  1166. }
  1167. // Find retrieve records from table, condiBeans's non-empty fields
  1168. // are conditions. beans could be []Struct, []*Struct, map[int64]Struct
  1169. // map[int64]*Struct
  1170. func (engine *Engine) Find(beans interface{}, condiBeans ...interface{}) error {
  1171. session := engine.NewSession()
  1172. defer session.Close()
  1173. return session.Find(beans, condiBeans...)
  1174. }
  1175. // Iterate record by record handle records from table, bean's non-empty fields
  1176. // are conditions.
  1177. func (engine *Engine) Iterate(bean interface{}, fun IterFunc) error {
  1178. session := engine.NewSession()
  1179. defer session.Close()
  1180. return session.Iterate(bean, fun)
  1181. }
  1182. // Return sql.Rows compatible Rows obj, as a forward Iterator object for iterating record by record, bean's non-empty fields
  1183. // are conditions.
  1184. func (engine *Engine) Rows(bean interface{}) (*Rows, error) {
  1185. session := engine.NewSession()
  1186. return session.Rows(bean)
  1187. }
  1188. // Count counts the records. bean's non-empty fields
  1189. // are conditions.
  1190. func (engine *Engine) Count(bean interface{}) (int64, error) {
  1191. session := engine.NewSession()
  1192. defer session.Close()
  1193. return session.Count(bean)
  1194. }
  1195. // Import SQL DDL file
  1196. func (engine *Engine) ImportFile(ddlPath string) ([]sql.Result, error) {
  1197. file, err := os.Open(ddlPath)
  1198. if err != nil {
  1199. return nil, err
  1200. }
  1201. defer file.Close()
  1202. return engine.Import(file)
  1203. }
  1204. // Import SQL DDL file
  1205. func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) {
  1206. var results []sql.Result
  1207. var lastError error
  1208. scanner := bufio.NewScanner(r)
  1209. semiColSpliter := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
  1210. if atEOF && len(data) == 0 {
  1211. return 0, nil, nil
  1212. }
  1213. if i := bytes.IndexByte(data, ';'); i >= 0 {
  1214. return i + 1, data[0:i], nil
  1215. }
  1216. // If we're at EOF, we have a final, non-terminated line. Return it.
  1217. if atEOF {
  1218. return len(data), data, nil
  1219. }
  1220. // Request more data.
  1221. return 0, nil, nil
  1222. }
  1223. scanner.Split(semiColSpliter)
  1224. for scanner.Scan() {
  1225. query := scanner.Text()
  1226. query = strings.Trim(query, " \t")
  1227. if len(query) > 0 {
  1228. result, err := engine.DB().Exec(query)
  1229. results = append(results, result)
  1230. if err != nil {
  1231. lastError = err
  1232. }
  1233. }
  1234. }
  1235. return results, lastError
  1236. }
  1237. var (
  1238. NULL_TIME time.Time
  1239. )
  1240. func (engine *Engine) TZTime(t time.Time) time.Time {
  1241. if NULL_TIME != t { // if time is not initialized it's not suitable for Time.In()
  1242. return t.In(engine.TZLocation)
  1243. }
  1244. return t
  1245. }
  1246. func (engine *Engine) NowTime(sqlTypeName string) interface{} {
  1247. t := time.Now()
  1248. return engine.FormatTime(sqlTypeName, t)
  1249. }
  1250. func (engine *Engine) NowTime2(sqlTypeName string) (interface{}, time.Time) {
  1251. t := time.Now()
  1252. return engine.FormatTime(sqlTypeName, t), t
  1253. }
  1254. func (engine *Engine) FormatTime(sqlTypeName string, t time.Time) (v interface{}) {
  1255. if engine.dialect.DBType() == core.ORACLE {
  1256. return t
  1257. }
  1258. switch sqlTypeName {
  1259. case core.Time:
  1260. s := engine.TZTime(t).Format("2006-01-02 15:04:05") //time.RFC3339
  1261. v = s[11:19]
  1262. case core.Date:
  1263. v = engine.TZTime(t).Format("2006-01-02")
  1264. case core.DateTime, core.TimeStamp:
  1265. if engine.dialect.DBType() == "ql" {
  1266. v = engine.TZTime(t)
  1267. } else if engine.dialect.DBType() == "sqlite3" {
  1268. v = engine.TZTime(t).UTC().Format("2006-01-02 15:04:05")
  1269. } else {
  1270. v = engine.TZTime(t).Format("2006-01-02 15:04:05")
  1271. }
  1272. case core.TimeStampz:
  1273. if engine.dialect.DBType() == core.MSSQL {
  1274. v = engine.TZTime(t).Format("2006-01-02T15:04:05.9999999Z07:00")
  1275. } else if engine.DriverName() == "mssql" {
  1276. v = engine.TZTime(t)
  1277. } else {
  1278. v = engine.TZTime(t).Format(time.RFC3339Nano)
  1279. }
  1280. case core.BigInt, core.Int:
  1281. v = engine.TZTime(t).Unix()
  1282. default:
  1283. v = engine.TZTime(t)
  1284. }
  1285. return
  1286. }
  1287. // Always disable struct tag "deleted"
  1288. func (engine *Engine) Unscoped() *Session {
  1289. session := engine.NewSession()
  1290. session.IsAutoClose = true
  1291. return session.Unscoped()
  1292. }