gorm.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package gorm
  2. import (
  3. "context"
  4. "time"
  5. "github.com/jinzhu/gorm/clause"
  6. "github.com/jinzhu/gorm/logger"
  7. "github.com/jinzhu/gorm/schema"
  8. )
  9. // Config GORM config
  10. type Config struct {
  11. // GORM perform single create, update, delete operations in transactions by default to ensure database data integrity
  12. // You can cancel it by setting `SkipDefaultTransaction` to true
  13. SkipDefaultTransaction bool // TODO
  14. // NamingStrategy tables, columns naming strategy
  15. NamingStrategy schema.Namer
  16. // Logger
  17. Logger logger.Interface
  18. // NowFunc the function to be used when creating a new timestamp
  19. NowFunc func() time.Time
  20. }
  21. // Dialector GORM database dialector
  22. type Dialector interface {
  23. Initialize(*DB) error
  24. Migrator() Migrator
  25. BindVar(stmt Statement, v interface{}) string
  26. }
  27. // DB GORM DB definition
  28. type DB struct {
  29. *Config
  30. Dialector
  31. Instance
  32. clone bool
  33. callbacks *callbacks
  34. }
  35. // Session session config when create new session
  36. type Session struct {
  37. Context context.Context
  38. Logger logger.Interface
  39. NowFunc func() time.Time
  40. }
  41. // Open initialize db session based on dialector
  42. func Open(dialector Dialector, config *Config) (db *DB, err error) {
  43. if config == nil {
  44. config = &Config{}
  45. }
  46. if config.NamingStrategy == nil {
  47. config.NamingStrategy = schema.NamingStrategy{}
  48. }
  49. if config.Logger == nil {
  50. config.Logger = logger.Default
  51. }
  52. if config.NowFunc == nil {
  53. config.NowFunc = func() time.Time { return time.Now().Local() }
  54. }
  55. db = &DB{
  56. Config: config,
  57. Dialector: dialector,
  58. clone: true,
  59. callbacks: InitializeCallbacks(),
  60. }
  61. if dialector != nil {
  62. err = dialector.Initialize(db)
  63. }
  64. return
  65. }
  66. // Session create new db session
  67. func (db *DB) Session(config *Session) *DB {
  68. var (
  69. tx = db.getInstance()
  70. txConfig = *tx.Config
  71. )
  72. if config.Context != nil {
  73. tx.Context = config.Context
  74. }
  75. if config.Logger != nil {
  76. txConfig.Logger = config.Logger
  77. }
  78. if config.NowFunc != nil {
  79. txConfig.NowFunc = config.NowFunc
  80. }
  81. tx.Config = &txConfig
  82. tx.clone = true
  83. return tx
  84. }
  85. // WithContext change current instance db's context to ctx
  86. func (db *DB) WithContext(ctx context.Context) *DB {
  87. return db.Session(&Session{Context: ctx})
  88. }
  89. // Debug start debug mode
  90. func (db *DB) Debug() (tx *DB) {
  91. return db.Session(&Session{Logger: db.Logger.LogMode(logger.Info)})
  92. }
  93. func (db *DB) Close() error {
  94. return nil
  95. }
  96. // Set store value with key into current db instance's context
  97. func (db *DB) Set(key string, value interface{}) *DB {
  98. tx := db.getInstance()
  99. tx.Statement.Settings.Store(key, value)
  100. return tx
  101. }
  102. // Get get value with key from current db instance's context
  103. func (db *DB) Get(key string) (interface{}, bool) {
  104. if db.Statement != nil {
  105. return db.Statement.Settings.Load(key)
  106. }
  107. return nil, false
  108. }
  109. // Callback returns callback manager
  110. func (db *DB) Callback() *callbacks {
  111. return db.callbacks
  112. }
  113. func (db *DB) getInstance() *DB {
  114. if db.clone {
  115. ctx := db.Instance.Context
  116. if ctx == nil {
  117. ctx = context.Background()
  118. }
  119. return &DB{
  120. Config: db.Config,
  121. Dialector: db.Dialector,
  122. Instance: Instance{
  123. Context: ctx,
  124. Statement: &Statement{DB: db, Clauses: map[string]clause.Clause{}},
  125. },
  126. }
  127. }
  128. return db
  129. }