engine.go 38 KB

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