engine.go 47 KB

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