functional option for gorm Config and add OpenWithOption create *db.DB with ConfigOption

This commit is contained in:
daheige 2021-02-06 10:41:15 +08:00
parent 3d3208ed60
commit 95fff37f1a
2 changed files with 221 additions and 0 deletions

147
config_option.go Normal file
View File

@ -0,0 +1,147 @@
package gorm
import (
"sync"
"time"
"gorm.io/gorm/clause"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
)
// ConfigOption use functional option for gorm Config.
type ConfigOption func(c *Config)
// WithSkipDefaultTransaction enable SkipDefaultTransaction.
func WithSkipDefaultTransaction() ConfigOption {
return func(c *Config) {
c.SkipDefaultTransaction = true
}
}
// WithNameStrategy set shema namer.
func WithNameStrategy(namer schema.Namer) ConfigOption {
return func(c *Config) {
c.NamingStrategy = namer
}
}
// WithFullSaveAssociations set FullSaveAssociations = true.
func WithFullSaveAssociations() ConfigOption {
return func(c *Config) {
c.FullSaveAssociations = true
}
}
// WithLogger set logger.
func WithLogger(logger logger.Interface) ConfigOption {
return func(c *Config) {
c.Logger = logger
}
}
// WithNowFunc set now func.
func WithNowFunc(fn func() time.Time) ConfigOption {
return func(c *Config) {
c.NowFunc = fn
}
}
// WithEnableDryRun enable dry run.
func WithEnableDryRun() ConfigOption {
return func(c *Config) {
c.DryRun = true
}
}
// WithPrepareStmt enable PrepareStmt.
func WithPrepareStmt() ConfigOption {
return func(c *Config) {
c.PrepareStmt = true
}
}
// WithEnableAutomaticPing enable ping.
func WithEnableAutomaticPing() ConfigOption {
return func(c *Config) {
c.DisableAutomaticPing = true
}
}
// WithEnableForeignKeyConstraintWhenMigrating
// ForeignKeyConstraintWhenMigrating config.
func WithEnableForeignKeyConstraintWhenMigrating() ConfigOption {
return func(c *Config) {
c.DisableForeignKeyConstraintWhenMigrating = true
}
}
// WithEnableNestedTransaction enable NestedTransaction.
func WithEnableNestedTransaction() ConfigOption {
return func(c *Config) {
c.DisableNestedTransaction = true
}
}
// WithAllowGlobalUpdate allow global update.
func WithAllowGlobalUpdate() ConfigOption {
return func(c *Config) {
c.AllowGlobalUpdate = true
}
}
// WithEnableQueryFields open QueryFields.
func WithEnableQueryFields() ConfigOption {
return func(c *Config) {
c.QueryFields = true
}
}
// WithCreateBatchSize set batch size.
func WithCreateBatchSize(size int) ConfigOption {
return func(c *Config) {
c.CreateBatchSize = size
}
}
// WithClauseBuilders set clause builder.
func WithClauseBuilders(m map[string]clause.ClauseBuilder) ConfigOption {
return func(c *Config) {
c.ClauseBuilders = m
}
}
// WithConnPool set conn pool.
func WithConnPool(connPool ConnPool) ConfigOption {
return func(c *Config) {
c.ConnPool = connPool
}
}
// WithDialector set dialector.
func WithDialector(dialector Dialector) ConfigOption {
return func(c *Config) {
c.Dialector = dialector
}
}
// WithConfigPlugins set config plugins.
func WithConfigPlugins(m map[string]Plugin) ConfigOption {
return func(c *Config) {
c.Plugins = m
}
}
// WithConfigCallbacks set cb for Config entry.
func WithConfigCallbacks(cb *callbacks) ConfigOption {
return func(c *Config) {
c.callbacks = cb
}
}
// WithCacheStore set cacheStore for Config entry.
func WithCacheStore(s *sync.Map) ConfigOption {
return func(c *Config) {
c.cacheStore = s
}
}

74
gorm.go
View File

@ -164,6 +164,80 @@ func Open(dialector Dialector, config *Config) (db *DB, err error) {
return
}
// DefaultConfig default config.
func DefaultConfig() *Config {
c := &Config{
NamingStrategy: schema.NamingStrategy{},
Logger: logger.Default,
NowFunc: func() time.Time { return time.Now().Local() },
ClauseBuilders: map[string]clause.ClauseBuilder{},
Plugins: map[string]Plugin{},
cacheStore: &sync.Map{},
}
return c
}
// Apply apply option for Config.
func (config *Config) Apply(opts ...ConfigOption) {
for _, o := range opts {
o(config)
}
}
// OpenWithOption create *db.DB with ConfigOption
// return *db.DB,error.
func OpenWithOption(dialector Dialector,
opts ...ConfigOption) (db *DB, err error) {
config := DefaultConfig()
// apply config option
config.Apply(opts...)
if dialector != nil {
config.Dialector = dialector
}
// create DB entry
db = &DB{Config: config, clone: 1}
db.callbacks = initializeCallbacks(db)
if config.Dialector != nil {
err = config.Dialector.Initialize(db)
}
preparedStmt := &PreparedStmtDB{
ConnPool: db.ConnPool,
Stmts: map[string]Stmt{},
Mux: &sync.RWMutex{},
PreparedSQL: make([]string, 0, 100),
}
db.cacheStore.Store("preparedStmt", preparedStmt)
if config.PrepareStmt {
db.ConnPool = preparedStmt
}
db.Statement = &Statement{
DB: db,
ConnPool: db.ConnPool,
Context: context.Background(),
Clauses: map[string]clause.Clause{},
}
if err == nil && !config.DisableAutomaticPing {
if pinger, ok := db.ConnPool.(interface{ Ping() error }); ok {
err = pinger.Ping()
}
}
if err != nil {
config.Logger.Error(context.Background(),
"failed to initialize database, got error %v", err)
}
return
}
// Session create new db session
func (db *DB) Session(config *Session) *DB {
var (