main.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  1. package gorm
  2. import (
  3. "context"
  4. "database/sql"
  5. "errors"
  6. "fmt"
  7. "reflect"
  8. "strings"
  9. "sync"
  10. "time"
  11. )
  12. // DB contains information for current db connection
  13. type DB struct {
  14. sync.RWMutex
  15. Value interface{}
  16. Error error
  17. RowsAffected int64
  18. // single db
  19. db SQLCommon
  20. blockGlobalUpdate bool
  21. logMode logModeValue
  22. logger logger
  23. search *search
  24. values sync.Map
  25. // global db
  26. parent *DB
  27. callbacks *Callback
  28. dialect Dialect
  29. singularTable bool
  30. // function to be used to override the creating of a new timestamp
  31. nowFuncOverride func() time.Time
  32. }
  33. type logModeValue int
  34. const (
  35. defaultLogMode logModeValue = iota
  36. noLogMode
  37. detailedLogMode
  38. )
  39. // Open initialize a new db connection, need to import driver first, e.g:
  40. //
  41. // import _ "github.com/go-sql-driver/mysql"
  42. // func main() {
  43. // db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
  44. // }
  45. // GORM has wrapped some drivers, for easier to remember driver's import path, so you could import the mysql driver with
  46. // import _ "github.com/jinzhu/gorm/dialects/mysql"
  47. // // import _ "github.com/jinzhu/gorm/dialects/postgres"
  48. // // import _ "github.com/jinzhu/gorm/dialects/sqlite"
  49. // // import _ "github.com/jinzhu/gorm/dialects/mssql"
  50. func Open(dialect string, args ...interface{}) (db *DB, err error) {
  51. if len(args) == 0 {
  52. err = errors.New("invalid database source")
  53. return nil, err
  54. }
  55. var source string
  56. var dbSQL SQLCommon
  57. var ownDbSQL bool
  58. switch value := args[0].(type) {
  59. case string:
  60. var driver = dialect
  61. if len(args) == 1 {
  62. source = value
  63. } else if len(args) >= 2 {
  64. driver = value
  65. source = args[1].(string)
  66. }
  67. dbSQL, err = sql.Open(driver, source)
  68. ownDbSQL = true
  69. case SQLCommon:
  70. dbSQL = value
  71. ownDbSQL = false
  72. default:
  73. return nil, fmt.Errorf("invalid database source: %v is not a valid type", value)
  74. }
  75. db = &DB{
  76. db: dbSQL,
  77. logger: defaultLogger,
  78. // Create a clone of the default logger to avoid mutating a shared object when
  79. // multiple gorm connections are created simultaneously.
  80. callbacks: DefaultCallback.clone(defaultLogger),
  81. dialect: newDialect(dialect, dbSQL),
  82. }
  83. db.parent = db
  84. if err != nil {
  85. return
  86. }
  87. // Send a ping to make sure the database connection is alive.
  88. if d, ok := dbSQL.(*sql.DB); ok {
  89. if err = d.Ping(); err != nil && ownDbSQL {
  90. d.Close()
  91. }
  92. }
  93. return
  94. }
  95. // New clone a new db connection without search conditions
  96. func (s *DB) New() *DB {
  97. clone := s.clone()
  98. clone.search = nil
  99. clone.Value = nil
  100. return clone
  101. }
  102. type closer interface {
  103. Close() error
  104. }
  105. // Close close current db connection. If database connection is not an io.Closer, returns an error.
  106. func (s *DB) Close() error {
  107. if db, ok := s.parent.db.(closer); ok {
  108. return db.Close()
  109. }
  110. return errors.New("can't close current db")
  111. }
  112. // DB get `*sql.DB` from current connection
  113. // If the underlying database connection is not a *sql.DB, returns nil
  114. func (s *DB) DB() *sql.DB {
  115. db, ok := s.db.(*sql.DB)
  116. if !ok {
  117. panic("can't support full GORM on currently status, maybe this is a TX instance.")
  118. }
  119. return db
  120. }
  121. // CommonDB return the underlying `*sql.DB` or `*sql.Tx` instance, mainly intended to allow coexistence with legacy non-GORM code.
  122. func (s *DB) CommonDB() SQLCommon {
  123. return s.db
  124. }
  125. // Dialect get dialect
  126. func (s *DB) Dialect() Dialect {
  127. return s.dialect
  128. }
  129. // Callback return `Callbacks` container, you could add/change/delete callbacks with it
  130. // db.Callback().Create().Register("update_created_at", updateCreated)
  131. // Refer https://jinzhu.github.io/gorm/development.html#callbacks
  132. func (s *DB) Callback() *Callback {
  133. s.parent.callbacks = s.parent.callbacks.clone(s.logger)
  134. return s.parent.callbacks
  135. }
  136. // SetLogger replace default logger
  137. func (s *DB) SetLogger(log logger) {
  138. s.logger = log
  139. }
  140. // LogMode set log mode, `true` for detailed logs, `false` for no log, default, will only print error logs
  141. func (s *DB) LogMode(enable bool) *DB {
  142. if enable {
  143. s.logMode = detailedLogMode
  144. } else {
  145. s.logMode = noLogMode
  146. }
  147. return s
  148. }
  149. // SetNowFuncOverride set the function to be used when creating a new timestamp
  150. func (s *DB) SetNowFuncOverride(nowFuncOverride func() time.Time) *DB {
  151. s.nowFuncOverride = nowFuncOverride
  152. return s
  153. }
  154. // Get a new timestamp, using the provided nowFuncOverride on the DB instance if set,
  155. // otherwise defaults to the global NowFunc()
  156. func (s *DB) nowFunc() time.Time {
  157. if s.nowFuncOverride != nil {
  158. return s.nowFuncOverride()
  159. }
  160. return NowFunc()
  161. }
  162. // BlockGlobalUpdate if true, generates an error on update/delete without where clause.
  163. // This is to prevent eventual error with empty objects updates/deletions
  164. func (s *DB) BlockGlobalUpdate(enable bool) *DB {
  165. s.blockGlobalUpdate = enable
  166. return s
  167. }
  168. // HasBlockGlobalUpdate return state of block
  169. func (s *DB) HasBlockGlobalUpdate() bool {
  170. return s.blockGlobalUpdate
  171. }
  172. // SingularTable use singular table by default
  173. func (s *DB) SingularTable(enable bool) {
  174. s.parent.Lock()
  175. defer s.parent.Unlock()
  176. s.parent.singularTable = enable
  177. }
  178. // NewScope create a scope for current operation
  179. func (s *DB) NewScope(value interface{}) *Scope {
  180. dbClone := s.clone()
  181. dbClone.Value = value
  182. scope := &Scope{db: dbClone, Value: value}
  183. if s.search != nil {
  184. scope.Search = s.search.clone()
  185. } else {
  186. scope.Search = &search{}
  187. }
  188. return scope
  189. }
  190. // QueryExpr returns the query as SqlExpr object
  191. func (s *DB) QueryExpr() *SqlExpr {
  192. scope := s.NewScope(s.Value)
  193. scope.InstanceSet("skip_bindvar", true)
  194. scope.prepareQuerySQL()
  195. return Expr(scope.SQL, scope.SQLVars...)
  196. }
  197. // SubQuery returns the query as sub query
  198. func (s *DB) SubQuery() *SqlExpr {
  199. scope := s.NewScope(s.Value)
  200. scope.InstanceSet("skip_bindvar", true)
  201. scope.prepareQuerySQL()
  202. return Expr(fmt.Sprintf("(%v)", scope.SQL), scope.SQLVars...)
  203. }
  204. // Where return a new relation, filter records with given conditions, accepts `map`, `struct` or `string` as conditions, refer http://jinzhu.github.io/gorm/crud.html#query
  205. func (s *DB) Where(query interface{}, args ...interface{}) *DB {
  206. return s.clone().search.Where(query, args...).db
  207. }
  208. // Or filter records that match before conditions or this one, similar to `Where`
  209. func (s *DB) Or(query interface{}, args ...interface{}) *DB {
  210. return s.clone().search.Or(query, args...).db
  211. }
  212. // Not filter records that don't match current conditions, similar to `Where`
  213. func (s *DB) Not(query interface{}, args ...interface{}) *DB {
  214. return s.clone().search.Not(query, args...).db
  215. }
  216. // Limit specify the number of records to be retrieved
  217. func (s *DB) Limit(limit interface{}) *DB {
  218. return s.clone().search.Limit(limit).db
  219. }
  220. // Offset specify the number of records to skip before starting to return the records
  221. func (s *DB) Offset(offset interface{}) *DB {
  222. return s.clone().search.Offset(offset).db
  223. }
  224. // Order specify order when retrieve records from database, set reorder to `true` to overwrite defined conditions
  225. // db.Order("name DESC")
  226. // db.Order("name DESC", true) // reorder
  227. // db.Order(gorm.Expr("name = ? DESC", "first")) // sql expression
  228. func (s *DB) Order(value interface{}, reorder ...bool) *DB {
  229. return s.clone().search.Order(value, reorder...).db
  230. }
  231. // Select specify fields that you want to retrieve from database when querying, by default, will select all fields;
  232. // When creating/updating, specify fields that you want to save to database
  233. func (s *DB) Select(query interface{}, args ...interface{}) *DB {
  234. return s.clone().search.Select(query, args...).db
  235. }
  236. // Omit specify fields that you want to ignore when saving to database for creating, updating
  237. func (s *DB) Omit(columns ...string) *DB {
  238. return s.clone().search.Omit(columns...).db
  239. }
  240. // Group specify the group method on the find
  241. func (s *DB) Group(query string) *DB {
  242. return s.clone().search.Group(query).db
  243. }
  244. // Having specify HAVING conditions for GROUP BY
  245. func (s *DB) Having(query interface{}, values ...interface{}) *DB {
  246. return s.clone().search.Having(query, values...).db
  247. }
  248. // Joins specify Joins conditions
  249. // db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").Find(&user)
  250. func (s *DB) Joins(query string, args ...interface{}) *DB {
  251. return s.clone().search.Joins(query, args...).db
  252. }
  253. // Scopes pass current database connection to arguments `func(*DB) *DB`, which could be used to add conditions dynamically
  254. // func AmountGreaterThan1000(db *gorm.DB) *gorm.DB {
  255. // return db.Where("amount > ?", 1000)
  256. // }
  257. //
  258. // func OrderStatus(status []string) func (db *gorm.DB) *gorm.DB {
  259. // return func (db *gorm.DB) *gorm.DB {
  260. // return db.Scopes(AmountGreaterThan1000).Where("status in (?)", status)
  261. // }
  262. // }
  263. //
  264. // db.Scopes(AmountGreaterThan1000, OrderStatus([]string{"paid", "shipped"})).Find(&orders)
  265. // Refer https://jinzhu.github.io/gorm/crud.html#scopes
  266. func (s *DB) Scopes(funcs ...func(*DB) *DB) *DB {
  267. for _, f := range funcs {
  268. s = f(s)
  269. }
  270. return s
  271. }
  272. // Unscoped return all record including deleted record, refer Soft Delete https://jinzhu.github.io/gorm/crud.html#soft-delete
  273. func (s *DB) Unscoped() *DB {
  274. return s.clone().search.unscoped().db
  275. }
  276. // Attrs initialize struct with argument if record not found with `FirstOrInit` https://jinzhu.github.io/gorm/crud.html#firstorinit or `FirstOrCreate` https://jinzhu.github.io/gorm/crud.html#firstorcreate
  277. func (s *DB) Attrs(attrs ...interface{}) *DB {
  278. return s.clone().search.Attrs(attrs...).db
  279. }
  280. // Assign assign result with argument regardless it is found or not with `FirstOrInit` https://jinzhu.github.io/gorm/crud.html#firstorinit or `FirstOrCreate` https://jinzhu.github.io/gorm/crud.html#firstorcreate
  281. func (s *DB) Assign(attrs ...interface{}) *DB {
  282. return s.clone().search.Assign(attrs...).db
  283. }
  284. // First find first record that match given conditions, order by primary key
  285. func (s *DB) First(out interface{}, where ...interface{}) *DB {
  286. newScope := s.NewScope(out)
  287. newScope.Search.Limit(1)
  288. return newScope.Set("gorm:order_by_primary_key", "ASC").
  289. inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
  290. }
  291. // Take return a record that match given conditions, the order will depend on the database implementation
  292. func (s *DB) Take(out interface{}, where ...interface{}) *DB {
  293. newScope := s.NewScope(out)
  294. newScope.Search.Limit(1)
  295. return newScope.inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
  296. }
  297. // Last find last record that match given conditions, order by primary key
  298. func (s *DB) Last(out interface{}, where ...interface{}) *DB {
  299. newScope := s.NewScope(out)
  300. newScope.Search.Limit(1)
  301. return newScope.Set("gorm:order_by_primary_key", "DESC").
  302. inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
  303. }
  304. // Find find records that match given conditions
  305. func (s *DB) Find(out interface{}, where ...interface{}) *DB {
  306. return s.NewScope(out).inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
  307. }
  308. //Preloads preloads relations, don`t touch out
  309. func (s *DB) Preloads(out interface{}) *DB {
  310. return s.NewScope(out).InstanceSet("gorm:only_preload", 1).callCallbacks(s.parent.callbacks.queries).db
  311. }
  312. // Scan scan value to a struct
  313. func (s *DB) Scan(dest interface{}) *DB {
  314. return s.NewScope(s.Value).Set("gorm:query_destination", dest).callCallbacks(s.parent.callbacks.queries).db
  315. }
  316. // Row return `*sql.Row` with given conditions
  317. func (s *DB) Row() *sql.Row {
  318. return s.NewScope(s.Value).row()
  319. }
  320. // Rows return `*sql.Rows` with given conditions
  321. func (s *DB) Rows() (*sql.Rows, error) {
  322. return s.NewScope(s.Value).rows()
  323. }
  324. // ScanRows scan `*sql.Rows` to give struct
  325. func (s *DB) ScanRows(rows *sql.Rows, result interface{}) error {
  326. var (
  327. scope = s.NewScope(result)
  328. clone = scope.db
  329. columns, err = rows.Columns()
  330. )
  331. if clone.AddError(err) == nil {
  332. scope.scan(rows, columns, scope.Fields())
  333. }
  334. return clone.Error
  335. }
  336. // Pluck used to query single column from a model as a map
  337. // var ages []int64
  338. // db.Find(&users).Pluck("age", &ages)
  339. func (s *DB) Pluck(column string, value interface{}) *DB {
  340. return s.NewScope(s.Value).pluck(column, value).db
  341. }
  342. // Count get how many records for a model
  343. func (s *DB) Count(value interface{}) *DB {
  344. return s.NewScope(s.Value).count(value).db
  345. }
  346. // Related get related associations
  347. func (s *DB) Related(value interface{}, foreignKeys ...string) *DB {
  348. return s.NewScope(s.Value).related(value, foreignKeys...).db
  349. }
  350. // FirstOrInit find first matched record or initialize a new one with given conditions (only works with struct, map conditions)
  351. // https://jinzhu.github.io/gorm/crud.html#firstorinit
  352. func (s *DB) FirstOrInit(out interface{}, where ...interface{}) *DB {
  353. c := s.clone()
  354. if result := c.First(out, where...); result.Error != nil {
  355. if !result.RecordNotFound() {
  356. return result
  357. }
  358. c.NewScope(out).inlineCondition(where...).initialize()
  359. } else {
  360. c.NewScope(out).updatedAttrsWithValues(c.search.assignAttrs)
  361. }
  362. return c
  363. }
  364. // FirstOrCreate find first matched record or create a new one with given conditions (only works with struct, map conditions)
  365. // https://jinzhu.github.io/gorm/crud.html#firstorcreate
  366. func (s *DB) FirstOrCreate(out interface{}, where ...interface{}) *DB {
  367. c := s.clone()
  368. if result := s.First(out, where...); result.Error != nil {
  369. if !result.RecordNotFound() {
  370. return result
  371. }
  372. return c.NewScope(out).inlineCondition(where...).initialize().callCallbacks(c.parent.callbacks.creates).db
  373. } else if len(c.search.assignAttrs) > 0 {
  374. return c.NewScope(out).InstanceSet("gorm:update_interface", c.search.assignAttrs).callCallbacks(c.parent.callbacks.updates).db
  375. }
  376. return c
  377. }
  378. // Update update attributes with callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update
  379. // WARNING when update with struct, GORM will not update fields that with zero value
  380. func (s *DB) Update(attrs ...interface{}) *DB {
  381. return s.Updates(toSearchableMap(attrs...), true)
  382. }
  383. // Updates update attributes with callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update
  384. func (s *DB) Updates(values interface{}, ignoreProtectedAttrs ...bool) *DB {
  385. return s.NewScope(s.Value).
  386. Set("gorm:ignore_protected_attrs", len(ignoreProtectedAttrs) > 0).
  387. InstanceSet("gorm:update_interface", values).
  388. callCallbacks(s.parent.callbacks.updates).db
  389. }
  390. // UpdateColumn update attributes without callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update
  391. func (s *DB) UpdateColumn(attrs ...interface{}) *DB {
  392. return s.UpdateColumns(toSearchableMap(attrs...))
  393. }
  394. // UpdateColumns update attributes without callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update
  395. func (s *DB) UpdateColumns(values interface{}) *DB {
  396. return s.NewScope(s.Value).
  397. Set("gorm:update_column", true).
  398. Set("gorm:save_associations", false).
  399. InstanceSet("gorm:update_interface", values).
  400. callCallbacks(s.parent.callbacks.updates).db
  401. }
  402. // Save update value in database, if the value doesn't have primary key, will insert it
  403. func (s *DB) Save(value interface{}) *DB {
  404. scope := s.NewScope(value)
  405. if !scope.PrimaryKeyZero() {
  406. newDB := scope.callCallbacks(s.parent.callbacks.updates).db
  407. if newDB.Error == nil && newDB.RowsAffected == 0 {
  408. return s.New().Table(scope.TableName()).FirstOrCreate(value)
  409. }
  410. return newDB
  411. }
  412. return scope.callCallbacks(s.parent.callbacks.creates).db
  413. }
  414. // Create insert the value into database
  415. func (s *DB) Create(value interface{}) *DB {
  416. scope := s.NewScope(value)
  417. return scope.callCallbacks(s.parent.callbacks.creates).db
  418. }
  419. // Delete delete value match given conditions, if the value has primary key, then will including the primary key as condition
  420. // WARNING If model has DeletedAt field, GORM will only set field DeletedAt's value to current time
  421. func (s *DB) Delete(value interface{}, where ...interface{}) *DB {
  422. return s.NewScope(value).inlineCondition(where...).callCallbacks(s.parent.callbacks.deletes).db
  423. }
  424. // Raw use raw sql as conditions, won't run it unless invoked by other methods
  425. // db.Raw("SELECT name, age FROM users WHERE name = ?", 3).Scan(&result)
  426. func (s *DB) Raw(sql string, values ...interface{}) *DB {
  427. return s.clone().search.Raw(true).Where(sql, values...).db
  428. }
  429. // Exec execute raw sql
  430. func (s *DB) Exec(sql string, values ...interface{}) *DB {
  431. scope := s.NewScope(nil)
  432. generatedSQL := scope.buildCondition(map[string]interface{}{"query": sql, "args": values}, true)
  433. generatedSQL = strings.TrimSuffix(strings.TrimPrefix(generatedSQL, "("), ")")
  434. scope.Raw(generatedSQL)
  435. return scope.Exec().db
  436. }
  437. // Model specify the model you would like to run db operations
  438. // // update all users's name to `hello`
  439. // db.Model(&User{}).Update("name", "hello")
  440. // // if user's primary key is non-blank, will use it as condition, then will only update the user's name to `hello`
  441. // db.Model(&user).Update("name", "hello")
  442. func (s *DB) Model(value interface{}) *DB {
  443. c := s.clone()
  444. c.Value = value
  445. return c
  446. }
  447. // Table specify the table you would like to run db operations
  448. func (s *DB) Table(name string) *DB {
  449. clone := s.clone()
  450. clone.search.Table(name)
  451. clone.Value = nil
  452. return clone
  453. }
  454. // Debug start debug mode
  455. func (s *DB) Debug() *DB {
  456. return s.clone().LogMode(true)
  457. }
  458. // Transaction start a transaction as a block,
  459. // return error will rollback, otherwise to commit.
  460. func (s *DB) Transaction(fc func(tx *DB) error) (err error) {
  461. if _, ok := s.db.(*sql.Tx); ok {
  462. return fc(s)
  463. }
  464. panicked := true
  465. tx := s.Begin()
  466. defer func() {
  467. // Make sure to rollback when panic, Block error or Commit error
  468. if panicked || err != nil {
  469. tx.Rollback()
  470. }
  471. }()
  472. err = fc(tx)
  473. if err == nil {
  474. err = tx.Commit().Error
  475. }
  476. panicked = false
  477. return
  478. }
  479. // Begin begins a transaction
  480. func (s *DB) Begin() *DB {
  481. return s.BeginTx(context.Background(), &sql.TxOptions{})
  482. }
  483. // BeginTx begins a transaction with options
  484. func (s *DB) BeginTx(ctx context.Context, opts *sql.TxOptions) *DB {
  485. c := s.clone()
  486. if db, ok := c.db.(sqlDb); ok && db != nil {
  487. tx, err := db.BeginTx(ctx, opts)
  488. c.db = interface{}(tx).(SQLCommon)
  489. c.dialect.SetDB(c.db)
  490. c.AddError(err)
  491. } else {
  492. c.AddError(ErrCantStartTransaction)
  493. }
  494. return c
  495. }
  496. // Commit commit a transaction
  497. func (s *DB) Commit() *DB {
  498. var emptySQLTx *sql.Tx
  499. if db, ok := s.db.(sqlTx); ok && db != nil && db != emptySQLTx {
  500. s.AddError(db.Commit())
  501. } else {
  502. s.AddError(ErrInvalidTransaction)
  503. }
  504. return s
  505. }
  506. // Rollback rollback a transaction
  507. func (s *DB) Rollback() *DB {
  508. var emptySQLTx *sql.Tx
  509. if db, ok := s.db.(sqlTx); ok && db != nil && db != emptySQLTx {
  510. if err := db.Rollback(); err != nil && err != sql.ErrTxDone {
  511. s.AddError(err)
  512. }
  513. } else {
  514. s.AddError(ErrInvalidTransaction)
  515. }
  516. return s
  517. }
  518. // RollbackUnlessCommitted rollback a transaction if it has not yet been
  519. // committed.
  520. func (s *DB) RollbackUnlessCommitted() *DB {
  521. var emptySQLTx *sql.Tx
  522. if db, ok := s.db.(sqlTx); ok && db != nil && db != emptySQLTx {
  523. err := db.Rollback()
  524. // Ignore the error indicating that the transaction has already
  525. // been committed.
  526. if err != sql.ErrTxDone {
  527. s.AddError(err)
  528. }
  529. } else {
  530. s.AddError(ErrInvalidTransaction)
  531. }
  532. return s
  533. }
  534. // NewRecord check if value's primary key is blank
  535. func (s *DB) NewRecord(value interface{}) bool {
  536. return s.NewScope(value).PrimaryKeyZero()
  537. }
  538. // RecordNotFound check if returning ErrRecordNotFound error
  539. func (s *DB) RecordNotFound() bool {
  540. for _, err := range s.GetErrors() {
  541. if err == ErrRecordNotFound {
  542. return true
  543. }
  544. }
  545. return false
  546. }
  547. // CreateTable create table for models
  548. func (s *DB) CreateTable(models ...interface{}) *DB {
  549. db := s.Unscoped()
  550. for _, model := range models {
  551. db = db.NewScope(model).createTable().db
  552. }
  553. return db
  554. }
  555. // DropTable drop table for models
  556. func (s *DB) DropTable(values ...interface{}) *DB {
  557. db := s.clone()
  558. for _, value := range values {
  559. if tableName, ok := value.(string); ok {
  560. db = db.Table(tableName)
  561. }
  562. db = db.NewScope(value).dropTable().db
  563. }
  564. return db
  565. }
  566. // DropTableIfExists drop table if it is exist
  567. func (s *DB) DropTableIfExists(values ...interface{}) *DB {
  568. db := s.clone()
  569. for _, value := range values {
  570. if s.HasTable(value) {
  571. db.AddError(s.DropTable(value).Error)
  572. }
  573. }
  574. return db
  575. }
  576. // HasTable check has table or not
  577. func (s *DB) HasTable(value interface{}) bool {
  578. var (
  579. scope = s.NewScope(value)
  580. tableName string
  581. )
  582. if name, ok := value.(string); ok {
  583. tableName = name
  584. } else {
  585. tableName = scope.TableName()
  586. }
  587. has := scope.Dialect().HasTable(tableName)
  588. s.AddError(scope.db.Error)
  589. return has
  590. }
  591. // AutoMigrate run auto migration for given models, will only add missing fields, won't delete/change current data
  592. func (s *DB) AutoMigrate(values ...interface{}) *DB {
  593. db := s.Unscoped()
  594. for _, value := range values {
  595. db = db.NewScope(value).autoMigrate().db
  596. }
  597. return db
  598. }
  599. // ModifyColumn modify column to type
  600. func (s *DB) ModifyColumn(column string, typ string) *DB {
  601. scope := s.NewScope(s.Value)
  602. scope.modifyColumn(column, typ)
  603. return scope.db
  604. }
  605. // DropColumn drop a column
  606. func (s *DB) DropColumn(column string) *DB {
  607. scope := s.NewScope(s.Value)
  608. scope.dropColumn(column)
  609. return scope.db
  610. }
  611. // AddIndex add index for columns with given name
  612. func (s *DB) AddIndex(indexName string, columns ...string) *DB {
  613. scope := s.Unscoped().NewScope(s.Value)
  614. scope.addIndex(false, indexName, columns...)
  615. return scope.db
  616. }
  617. // AddUniqueIndex add unique index for columns with given name
  618. func (s *DB) AddUniqueIndex(indexName string, columns ...string) *DB {
  619. scope := s.Unscoped().NewScope(s.Value)
  620. scope.addIndex(true, indexName, columns...)
  621. return scope.db
  622. }
  623. // RemoveIndex remove index with name
  624. func (s *DB) RemoveIndex(indexName string) *DB {
  625. scope := s.NewScope(s.Value)
  626. scope.removeIndex(indexName)
  627. return scope.db
  628. }
  629. // AddForeignKey Add foreign key to the given scope, e.g:
  630. // db.Model(&User{}).AddForeignKey("city_id", "cities(id)", "RESTRICT", "RESTRICT")
  631. func (s *DB) AddForeignKey(field string, dest string, onDelete string, onUpdate string) *DB {
  632. scope := s.NewScope(s.Value)
  633. scope.addForeignKey(field, dest, onDelete, onUpdate)
  634. return scope.db
  635. }
  636. // RemoveForeignKey Remove foreign key from the given scope, e.g:
  637. // db.Model(&User{}).RemoveForeignKey("city_id", "cities(id)")
  638. func (s *DB) RemoveForeignKey(field string, dest string) *DB {
  639. scope := s.clone().NewScope(s.Value)
  640. scope.removeForeignKey(field, dest)
  641. return scope.db
  642. }
  643. // Association start `Association Mode` to handler relations things easir in that mode, refer: https://jinzhu.github.io/gorm/associations.html#association-mode
  644. func (s *DB) Association(column string) *Association {
  645. var err error
  646. var scope = s.Set("gorm:association:source", s.Value).NewScope(s.Value)
  647. if primaryField := scope.PrimaryField(); primaryField.IsBlank {
  648. err = errors.New("primary key can't be nil")
  649. } else {
  650. if field, ok := scope.FieldByName(column); ok {
  651. if field.Relationship == nil || len(field.Relationship.ForeignFieldNames) == 0 {
  652. err = fmt.Errorf("invalid association %v for %v", column, scope.IndirectValue().Type())
  653. } else {
  654. return &Association{scope: scope, column: column, field: field}
  655. }
  656. } else {
  657. err = fmt.Errorf("%v doesn't have column %v", scope.IndirectValue().Type(), column)
  658. }
  659. }
  660. return &Association{Error: err}
  661. }
  662. // Preload preload associations with given conditions
  663. // db.Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)
  664. func (s *DB) Preload(column string, conditions ...interface{}) *DB {
  665. return s.clone().search.Preload(column, conditions...).db
  666. }
  667. // Set set setting by name, which could be used in callbacks, will clone a new db, and update its setting
  668. func (s *DB) Set(name string, value interface{}) *DB {
  669. return s.clone().InstantSet(name, value)
  670. }
  671. // InstantSet instant set setting, will affect current db
  672. func (s *DB) InstantSet(name string, value interface{}) *DB {
  673. s.values.Store(name, value)
  674. return s
  675. }
  676. // Get get setting by name
  677. func (s *DB) Get(name string) (value interface{}, ok bool) {
  678. value, ok = s.values.Load(name)
  679. return
  680. }
  681. // SetJoinTableHandler set a model's join table handler for a relation
  682. func (s *DB) SetJoinTableHandler(source interface{}, column string, handler JoinTableHandlerInterface) {
  683. scope := s.NewScope(source)
  684. for _, field := range scope.GetModelStruct().StructFields {
  685. if field.Name == column || field.DBName == column {
  686. if many2many, _ := field.TagSettingsGet("MANY2MANY"); many2many != "" {
  687. source := (&Scope{Value: source}).GetModelStruct().ModelType
  688. destination := (&Scope{Value: reflect.New(field.Struct.Type).Interface()}).GetModelStruct().ModelType
  689. handler.Setup(field.Relationship, many2many, source, destination)
  690. field.Relationship.JoinTableHandler = handler
  691. if table := handler.Table(s); scope.Dialect().HasTable(table) {
  692. s.Table(table).AutoMigrate(handler)
  693. }
  694. }
  695. }
  696. }
  697. }
  698. // AddError add error to the db
  699. func (s *DB) AddError(err error) error {
  700. if err != nil {
  701. if err != ErrRecordNotFound {
  702. if s.logMode == defaultLogMode {
  703. go s.print("error", fileWithLineNum(), err)
  704. } else {
  705. s.log(err)
  706. }
  707. errors := Errors(s.GetErrors())
  708. errors = errors.Add(err)
  709. if len(errors) > 1 {
  710. err = errors
  711. }
  712. }
  713. s.Error = err
  714. }
  715. return err
  716. }
  717. // GetErrors get happened errors from the db
  718. func (s *DB) GetErrors() []error {
  719. if errs, ok := s.Error.(Errors); ok {
  720. return errs
  721. } else if s.Error != nil {
  722. return []error{s.Error}
  723. }
  724. return []error{}
  725. }
  726. ////////////////////////////////////////////////////////////////////////////////
  727. // Private Methods For DB
  728. ////////////////////////////////////////////////////////////////////////////////
  729. func (s *DB) clone() *DB {
  730. db := &DB{
  731. db: s.db,
  732. parent: s.parent,
  733. logger: s.logger,
  734. logMode: s.logMode,
  735. Value: s.Value,
  736. Error: s.Error,
  737. blockGlobalUpdate: s.blockGlobalUpdate,
  738. dialect: newDialect(s.dialect.GetName(), s.db),
  739. nowFuncOverride: s.nowFuncOverride,
  740. }
  741. s.values.Range(func(k, v interface{}) bool {
  742. db.values.Store(k, v)
  743. return true
  744. })
  745. if s.search == nil {
  746. db.search = &search{limit: -1, offset: -1}
  747. } else {
  748. db.search = s.search.clone()
  749. }
  750. db.search.db = db
  751. return db
  752. }
  753. func (s *DB) print(v ...interface{}) {
  754. s.logger.Print(v...)
  755. }
  756. func (s *DB) log(v ...interface{}) {
  757. if s != nil && s.logMode == detailedLogMode {
  758. s.print(append([]interface{}{"log", fileWithLineNum()}, v...)...)
  759. }
  760. }
  761. func (s *DB) slog(sql string, t time.Time, vars ...interface{}) {
  762. if s.logMode == detailedLogMode {
  763. s.print("sql", fileWithLineNum(), NowFunc().Sub(t), sql, vars, s.RowsAffected)
  764. }
  765. }