From f580a714d5748d86d2c2ad6915030253162c2aa5 Mon Sep 17 00:00:00 2001 From: Ming Deng Date: Tue, 8 Sep 2020 20:47:39 +0800 Subject: [PATCH] Optimize orm by using BDOption rather than hints --- pkg/adapter/orm/db_alias.go | 8 ++- pkg/client/orm/db_alias.go | 77 +++++++++++++++++---------- pkg/client/orm/db_alias_test.go | 16 +++--- pkg/client/orm/hints/db_hints.go | 30 +---------- pkg/client/orm/hints/db_hints_test.go | 28 ---------- pkg/client/orm/models_test.go | 4 +- pkg/client/orm/orm.go | 2 +- 7 files changed, 63 insertions(+), 102 deletions(-) diff --git a/pkg/adapter/orm/db_alias.go b/pkg/adapter/orm/db_alias.go index 2ecc80e5..b1f1a724 100644 --- a/pkg/adapter/orm/db_alias.go +++ b/pkg/adapter/orm/db_alias.go @@ -20,8 +20,6 @@ import ( "time" "github.com/astaxie/beego/pkg/client/orm" - "github.com/astaxie/beego/pkg/client/orm/hints" - "github.com/astaxie/beego/pkg/infrastructure/utils" ) // DriverType database driver constant int. @@ -86,13 +84,13 @@ func AddAliasWthDB(aliasName, driverName string, db *sql.DB) error { // RegisterDataBase Setting the database connect params. Use the database driver self dataSource args. func RegisterDataBase(aliasName, driverName, dataSource string, params ...int) error { - opts := make([]utils.KV, 0, 2) + opts := make([]orm.DBOption, 0, 2) if len(params) > 0 { - opts = append(opts, hints.MaxIdleConnections(params[0])) + opts = append(opts, orm.MaxIdleConnections(params[0])) } if len(params) > 1 { - opts = append(opts, hints.MaxOpenConnections(params[1])) + opts = append(opts, orm.MaxOpenConnections(params[1])) } return orm.RegisterDataBase(aliasName, driverName, dataSource, opts...) } diff --git a/pkg/client/orm/db_alias.go b/pkg/client/orm/db_alias.go index c72f29c4..29e0904c 100644 --- a/pkg/client/orm/db_alias.go +++ b/pkg/client/orm/db_alias.go @@ -21,9 +21,6 @@ import ( "sync" "time" - "github.com/astaxie/beego/pkg/client/orm/hints" - "github.com/astaxie/beego/pkg/infrastructure/utils" - lru "github.com/hashicorp/golang-lru" ) @@ -278,6 +275,7 @@ type alias struct { MaxIdleConns int MaxOpenConns int ConnMaxLifetime time.Duration + StmtCacheSize int DB *DB DbBaser dbBaser TZ *time.Location @@ -340,7 +338,7 @@ func detectTZ(al *alias) { } } -func addAliasWthDB(aliasName, driverName string, db *sql.DB, params ...utils.KV) (*alias, error) { +func addAliasWthDB(aliasName, driverName string, db *sql.DB, params ...DBOption) (*alias, error) { existErr := fmt.Errorf("DataBase alias name `%s` already registered, cannot reuse", aliasName) if _, ok := dataBaseCache.get(aliasName); ok { return nil, existErr @@ -358,32 +356,35 @@ func addAliasWthDB(aliasName, driverName string, db *sql.DB, params ...utils.KV) return al, nil } -func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...utils.KV) (*alias, error) { - kvs := utils.NewKVs(params...) +func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...DBOption) (*alias, error) { + + al := &alias{} + al.DB = &DB{ + RWMutex: new(sync.RWMutex), + DB: db, + } + + for _, p := range params { + p(al) + } var stmtCache *lru.Cache var stmtCacheSize int - maxStmtCacheSize := kvs.GetValueOr(hints.KeyMaxStmtCacheSize, 0).(int) - if maxStmtCacheSize > 0 { - _stmtCache, errC := newStmtDecoratorLruWithEvict(maxStmtCacheSize) + if al.StmtCacheSize > 0 { + _stmtCache, errC := newStmtDecoratorLruWithEvict(al.StmtCacheSize) if errC != nil { return nil, errC } else { stmtCache = _stmtCache - stmtCacheSize = maxStmtCacheSize + stmtCacheSize = al.StmtCacheSize } } - al := new(alias) al.Name = aliasName al.DriverName = driverName - al.DB = &DB{ - RWMutex: new(sync.RWMutex), - DB: db, - stmtDecorators: stmtCache, - stmtDecoratorsLimit: stmtCacheSize, - } + al.DB.stmtDecorators = stmtCache + al.DB.stmtDecoratorsLimit = stmtCacheSize if dr, ok := drivers[driverName]; ok { al.DbBaser = dbBasers[dr] @@ -399,14 +400,6 @@ func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...utils.KV detectTZ(al) - kvs.IfContains(hints.KeyMaxIdleConnections, func(value interface{}) { - al.SetMaxIdleConns(value.(int)) - }).IfContains(hints.KeyMaxOpenConnections, func(value interface{}) { - al.SetMaxOpenConns(value.(int)) - }).IfContains(hints.KeyConnMaxLifetime, func(value interface{}) { - al.SetConnMaxLifetime(value.(time.Duration)) - }) - return al, nil } @@ -442,13 +435,13 @@ func (al *alias) SetConnMaxLifetime(lifeTime time.Duration) { } // AddAliasWthDB add a aliasName for the drivename -func AddAliasWthDB(aliasName, driverName string, db *sql.DB, params ...utils.KV) error { +func AddAliasWthDB(aliasName, driverName string, db *sql.DB, params ...DBOption) error { _, err := addAliasWthDB(aliasName, driverName, db, params...) return err } // RegisterDataBase Setting the database connect params. Use the database driver self dataSource args. -func RegisterDataBase(aliasName, driverName, dataSource string, params ...utils.KV) error { +func RegisterDataBase(aliasName, driverName, dataSource string, params ...DBOption) error { var ( err error db *sql.DB @@ -561,3 +554,33 @@ func newStmtDecoratorLruWithEvict(cacheSize int) (*lru.Cache, error) { } return cache, nil } + +type DBOption func(al *alias) + +// MaxIdleConnections return a hint about MaxIdleConnections +func MaxIdleConnections(maxIdleConn int) DBOption { + return func(al *alias) { + al.SetMaxIdleConns(maxIdleConn) + } +} + +// MaxOpenConnections return a hint about MaxOpenConnections +func MaxOpenConnections(maxOpenConn int) DBOption { + return func(al *alias) { + al.SetMaxOpenConns(maxOpenConn) + } +} + +// ConnMaxLifetime return a hint about ConnMaxLifetime +func ConnMaxLifetime(v time.Duration) DBOption { + return func(al *alias) { + al.SetConnMaxLifetime(v) + } +} + +// MaxStmtCacheSize return a hint about MaxStmtCacheSize +func MaxStmtCacheSize(v int) DBOption { + return func(al *alias) { + al.StmtCacheSize = v + } +} diff --git a/pkg/client/orm/db_alias_test.go b/pkg/client/orm/db_alias_test.go index 0043ba76..6275cb2a 100644 --- a/pkg/client/orm/db_alias_test.go +++ b/pkg/client/orm/db_alias_test.go @@ -18,16 +18,14 @@ import ( "testing" "time" - "github.com/astaxie/beego/pkg/client/orm/hints" - "github.com/stretchr/testify/assert" ) func TestRegisterDataBase(t *testing.T) { err := RegisterDataBase("test-params", DBARGS.Driver, DBARGS.Source, - hints.MaxIdleConnections(20), - hints.MaxOpenConnections(300), - hints.ConnMaxLifetime(time.Minute)) + MaxIdleConnections(20), + MaxOpenConnections(300), + ConnMaxLifetime(time.Minute)) assert.Nil(t, err) al := getDbAlias("test-params") @@ -39,7 +37,7 @@ func TestRegisterDataBase(t *testing.T) { func TestRegisterDataBase_MaxStmtCacheSizeNegative1(t *testing.T) { aliasName := "TestRegisterDataBase_MaxStmtCacheSizeNegative1" - err := RegisterDataBase(aliasName, DBARGS.Driver, DBARGS.Source, hints.MaxStmtCacheSize(-1)) + err := RegisterDataBase(aliasName, DBARGS.Driver, DBARGS.Source, MaxStmtCacheSize(-1)) assert.Nil(t, err) al := getDbAlias(aliasName) @@ -49,7 +47,7 @@ func TestRegisterDataBase_MaxStmtCacheSizeNegative1(t *testing.T) { func TestRegisterDataBase_MaxStmtCacheSize0(t *testing.T) { aliasName := "TestRegisterDataBase_MaxStmtCacheSize0" - err := RegisterDataBase(aliasName, DBARGS.Driver, DBARGS.Source, hints.MaxStmtCacheSize(0)) + err := RegisterDataBase(aliasName, DBARGS.Driver, DBARGS.Source, MaxStmtCacheSize(0)) assert.Nil(t, err) al := getDbAlias(aliasName) @@ -59,7 +57,7 @@ func TestRegisterDataBase_MaxStmtCacheSize0(t *testing.T) { func TestRegisterDataBase_MaxStmtCacheSize1(t *testing.T) { aliasName := "TestRegisterDataBase_MaxStmtCacheSize1" - err := RegisterDataBase(aliasName, DBARGS.Driver, DBARGS.Source, hints.MaxStmtCacheSize(1)) + err := RegisterDataBase(aliasName, DBARGS.Driver, DBARGS.Source, MaxStmtCacheSize(1)) assert.Nil(t, err) al := getDbAlias(aliasName) @@ -69,7 +67,7 @@ func TestRegisterDataBase_MaxStmtCacheSize1(t *testing.T) { func TestRegisterDataBase_MaxStmtCacheSize841(t *testing.T) { aliasName := "TestRegisterDataBase_MaxStmtCacheSize841" - err := RegisterDataBase(aliasName, DBARGS.Driver, DBARGS.Source, hints.MaxStmtCacheSize(841)) + err := RegisterDataBase(aliasName, DBARGS.Driver, DBARGS.Source, MaxStmtCacheSize(841)) assert.Nil(t, err) al := getDbAlias(aliasName) diff --git a/pkg/client/orm/hints/db_hints.go b/pkg/client/orm/hints/db_hints.go index 4d199312..7340bd07 100644 --- a/pkg/client/orm/hints/db_hints.go +++ b/pkg/client/orm/hints/db_hints.go @@ -15,20 +15,12 @@ package hints import ( - "time" - "github.com/astaxie/beego/pkg/infrastructure/utils" ) const ( - //db level - KeyMaxIdleConnections = iota - KeyMaxOpenConnections - KeyConnMaxLifetime - KeyMaxStmtCacheSize - //query level - KeyForceIndex + KeyForceIndex = iota KeyUseIndex KeyIgnoreIndex KeyForUpdate @@ -57,26 +49,6 @@ func (s *Hint) GetValue() interface{} { var _ utils.KV = new(Hint) -// MaxIdleConnections return a hint about MaxIdleConnections -func MaxIdleConnections(v int) *Hint { - return NewHint(KeyMaxIdleConnections, v) -} - -// MaxOpenConnections return a hint about MaxOpenConnections -func MaxOpenConnections(v int) *Hint { - return NewHint(KeyMaxOpenConnections, v) -} - -// ConnMaxLifetime return a hint about ConnMaxLifetime -func ConnMaxLifetime(v time.Duration) *Hint { - return NewHint(KeyConnMaxLifetime, v) -} - -// MaxStmtCacheSize return a hint about MaxStmtCacheSize -func MaxStmtCacheSize(v int) *Hint { - return NewHint(KeyMaxStmtCacheSize, v) -} - // ForceIndex return a hint about ForceIndex func ForceIndex(indexes ...string) *Hint { return NewHint(KeyForceIndex, indexes) diff --git a/pkg/client/orm/hints/db_hints_test.go b/pkg/client/orm/hints/db_hints_test.go index 4e962a8f..510f9f16 100644 --- a/pkg/client/orm/hints/db_hints_test.go +++ b/pkg/client/orm/hints/db_hints_test.go @@ -48,34 +48,6 @@ func TestNewHint_float(t *testing.T) { assert.Equal(t, hint.GetValue(), value) } -func TestMaxOpenConnections(t *testing.T) { - i := 887423 - hint := MaxOpenConnections(i) - assert.Equal(t, hint.GetValue(), i) - assert.Equal(t, hint.GetKey(), KeyMaxOpenConnections) -} - -func TestConnMaxLifetime(t *testing.T) { - i := time.Hour - hint := ConnMaxLifetime(i) - assert.Equal(t, hint.GetValue(), i) - assert.Equal(t, hint.GetKey(), KeyConnMaxLifetime) -} - -func TestMaxIdleConnections(t *testing.T) { - i := 42316 - hint := MaxIdleConnections(i) - assert.Equal(t, hint.GetValue(), i) - assert.Equal(t, hint.GetKey(), KeyMaxIdleConnections) -} - -func TestMaxStmtCacheSize(t *testing.T) { - i := 94157 - hint := MaxStmtCacheSize(i) - assert.Equal(t, hint.GetValue(), i) - assert.Equal(t, hint.GetKey(), KeyMaxStmtCacheSize) -} - func TestForceIndex(t *testing.T) { s := []string{`f_index1`, `f_index2`, `f_index3`} hint := ForceIndex(s...) diff --git a/pkg/client/orm/models_test.go b/pkg/client/orm/models_test.go index 81ba30df..f0044f6d 100644 --- a/pkg/client/orm/models_test.go +++ b/pkg/client/orm/models_test.go @@ -22,8 +22,6 @@ import ( "strings" "time" - "github.com/astaxie/beego/pkg/client/orm/hints" - _ "github.com/go-sql-driver/mysql" _ "github.com/lib/pq" _ "github.com/mattn/go-sqlite3" @@ -529,7 +527,7 @@ func init() { os.Exit(2) } - err := RegisterDataBase("default", DBARGS.Driver, DBARGS.Source, hints.MaxIdleConnections(20)) + err := RegisterDataBase("default", DBARGS.Driver, DBARGS.Source, MaxIdleConnections(20)) if err != nil { panic(fmt.Sprintf("can not register database: %v", err)) diff --git a/pkg/client/orm/orm.go b/pkg/client/orm/orm.go index 95bbcb31..bfb710d1 100644 --- a/pkg/client/orm/orm.go +++ b/pkg/client/orm/orm.go @@ -601,7 +601,7 @@ func NewOrmUsingDB(aliasName string) Ormer { } // NewOrmWithDB create a new ormer object with specify *sql.DB for query -func NewOrmWithDB(driverName, aliasName string, db *sql.DB, params ...utils.KV) (Ormer, error) { +func NewOrmWithDB(driverName, aliasName string, db *sql.DB, params ...DBOption) (Ormer, error) { al, err := newAliasWithDb(aliasName, driverName, db, params...) if err != nil { return nil, err