1
0
mirror of https://github.com/astaxie/beego.git synced 2024-11-22 14:10:54 +00:00

Optimize orm by using BDOption rather than hints

This commit is contained in:
Ming Deng 2020-09-08 20:47:39 +08:00
parent 9ccd58bfff
commit f580a714d5
7 changed files with 63 additions and 102 deletions

View File

@ -20,8 +20,6 @@ import (
"time" "time"
"github.com/astaxie/beego/pkg/client/orm" "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. // 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. // RegisterDataBase Setting the database connect params. Use the database driver self dataSource args.
func RegisterDataBase(aliasName, driverName, dataSource string, params ...int) error { 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 { if len(params) > 0 {
opts = append(opts, hints.MaxIdleConnections(params[0])) opts = append(opts, orm.MaxIdleConnections(params[0]))
} }
if len(params) > 1 { 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...) return orm.RegisterDataBase(aliasName, driverName, dataSource, opts...)
} }

View File

@ -21,9 +21,6 @@ import (
"sync" "sync"
"time" "time"
"github.com/astaxie/beego/pkg/client/orm/hints"
"github.com/astaxie/beego/pkg/infrastructure/utils"
lru "github.com/hashicorp/golang-lru" lru "github.com/hashicorp/golang-lru"
) )
@ -278,6 +275,7 @@ type alias struct {
MaxIdleConns int MaxIdleConns int
MaxOpenConns int MaxOpenConns int
ConnMaxLifetime time.Duration ConnMaxLifetime time.Duration
StmtCacheSize int
DB *DB DB *DB
DbBaser dbBaser DbBaser dbBaser
TZ *time.Location 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) existErr := fmt.Errorf("DataBase alias name `%s` already registered, cannot reuse", aliasName)
if _, ok := dataBaseCache.get(aliasName); ok { if _, ok := dataBaseCache.get(aliasName); ok {
return nil, existErr return nil, existErr
@ -358,32 +356,35 @@ func addAliasWthDB(aliasName, driverName string, db *sql.DB, params ...utils.KV)
return al, nil return al, nil
} }
func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...utils.KV) (*alias, error) { func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...DBOption) (*alias, error) {
kvs := utils.NewKVs(params...)
al := &alias{}
al.DB = &DB{
RWMutex: new(sync.RWMutex),
DB: db,
}
for _, p := range params {
p(al)
}
var stmtCache *lru.Cache var stmtCache *lru.Cache
var stmtCacheSize int var stmtCacheSize int
maxStmtCacheSize := kvs.GetValueOr(hints.KeyMaxStmtCacheSize, 0).(int) if al.StmtCacheSize > 0 {
if maxStmtCacheSize > 0 { _stmtCache, errC := newStmtDecoratorLruWithEvict(al.StmtCacheSize)
_stmtCache, errC := newStmtDecoratorLruWithEvict(maxStmtCacheSize)
if errC != nil { if errC != nil {
return nil, errC return nil, errC
} else { } else {
stmtCache = _stmtCache stmtCache = _stmtCache
stmtCacheSize = maxStmtCacheSize stmtCacheSize = al.StmtCacheSize
} }
} }
al := new(alias)
al.Name = aliasName al.Name = aliasName
al.DriverName = driverName al.DriverName = driverName
al.DB = &DB{ al.DB.stmtDecorators = stmtCache
RWMutex: new(sync.RWMutex), al.DB.stmtDecoratorsLimit = stmtCacheSize
DB: db,
stmtDecorators: stmtCache,
stmtDecoratorsLimit: stmtCacheSize,
}
if dr, ok := drivers[driverName]; ok { if dr, ok := drivers[driverName]; ok {
al.DbBaser = dbBasers[dr] al.DbBaser = dbBasers[dr]
@ -399,14 +400,6 @@ func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...utils.KV
detectTZ(al) 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 return al, nil
} }
@ -442,13 +435,13 @@ func (al *alias) SetConnMaxLifetime(lifeTime time.Duration) {
} }
// AddAliasWthDB add a aliasName for the drivename // 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...) _, err := addAliasWthDB(aliasName, driverName, db, params...)
return err return err
} }
// RegisterDataBase Setting the database connect params. Use the database driver self dataSource args. // 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 ( var (
err error err error
db *sql.DB db *sql.DB
@ -561,3 +554,33 @@ func newStmtDecoratorLruWithEvict(cacheSize int) (*lru.Cache, error) {
} }
return cache, nil 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
}
}

View File

@ -18,16 +18,14 @@ import (
"testing" "testing"
"time" "time"
"github.com/astaxie/beego/pkg/client/orm/hints"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestRegisterDataBase(t *testing.T) { func TestRegisterDataBase(t *testing.T) {
err := RegisterDataBase("test-params", DBARGS.Driver, DBARGS.Source, err := RegisterDataBase("test-params", DBARGS.Driver, DBARGS.Source,
hints.MaxIdleConnections(20), MaxIdleConnections(20),
hints.MaxOpenConnections(300), MaxOpenConnections(300),
hints.ConnMaxLifetime(time.Minute)) ConnMaxLifetime(time.Minute))
assert.Nil(t, err) assert.Nil(t, err)
al := getDbAlias("test-params") al := getDbAlias("test-params")
@ -39,7 +37,7 @@ func TestRegisterDataBase(t *testing.T) {
func TestRegisterDataBase_MaxStmtCacheSizeNegative1(t *testing.T) { func TestRegisterDataBase_MaxStmtCacheSizeNegative1(t *testing.T) {
aliasName := "TestRegisterDataBase_MaxStmtCacheSizeNegative1" 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) assert.Nil(t, err)
al := getDbAlias(aliasName) al := getDbAlias(aliasName)
@ -49,7 +47,7 @@ func TestRegisterDataBase_MaxStmtCacheSizeNegative1(t *testing.T) {
func TestRegisterDataBase_MaxStmtCacheSize0(t *testing.T) { func TestRegisterDataBase_MaxStmtCacheSize0(t *testing.T) {
aliasName := "TestRegisterDataBase_MaxStmtCacheSize0" 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) assert.Nil(t, err)
al := getDbAlias(aliasName) al := getDbAlias(aliasName)
@ -59,7 +57,7 @@ func TestRegisterDataBase_MaxStmtCacheSize0(t *testing.T) {
func TestRegisterDataBase_MaxStmtCacheSize1(t *testing.T) { func TestRegisterDataBase_MaxStmtCacheSize1(t *testing.T) {
aliasName := "TestRegisterDataBase_MaxStmtCacheSize1" 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) assert.Nil(t, err)
al := getDbAlias(aliasName) al := getDbAlias(aliasName)
@ -69,7 +67,7 @@ func TestRegisterDataBase_MaxStmtCacheSize1(t *testing.T) {
func TestRegisterDataBase_MaxStmtCacheSize841(t *testing.T) { func TestRegisterDataBase_MaxStmtCacheSize841(t *testing.T) {
aliasName := "TestRegisterDataBase_MaxStmtCacheSize841" 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) assert.Nil(t, err)
al := getDbAlias(aliasName) al := getDbAlias(aliasName)

View File

@ -15,20 +15,12 @@
package hints package hints
import ( import (
"time"
"github.com/astaxie/beego/pkg/infrastructure/utils" "github.com/astaxie/beego/pkg/infrastructure/utils"
) )
const ( const (
//db level
KeyMaxIdleConnections = iota
KeyMaxOpenConnections
KeyConnMaxLifetime
KeyMaxStmtCacheSize
//query level //query level
KeyForceIndex KeyForceIndex = iota
KeyUseIndex KeyUseIndex
KeyIgnoreIndex KeyIgnoreIndex
KeyForUpdate KeyForUpdate
@ -57,26 +49,6 @@ func (s *Hint) GetValue() interface{} {
var _ utils.KV = new(Hint) 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 // ForceIndex return a hint about ForceIndex
func ForceIndex(indexes ...string) *Hint { func ForceIndex(indexes ...string) *Hint {
return NewHint(KeyForceIndex, indexes) return NewHint(KeyForceIndex, indexes)

View File

@ -48,34 +48,6 @@ func TestNewHint_float(t *testing.T) {
assert.Equal(t, hint.GetValue(), value) 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) { func TestForceIndex(t *testing.T) {
s := []string{`f_index1`, `f_index2`, `f_index3`} s := []string{`f_index1`, `f_index2`, `f_index3`}
hint := ForceIndex(s...) hint := ForceIndex(s...)

View File

@ -22,8 +22,6 @@ import (
"strings" "strings"
"time" "time"
"github.com/astaxie/beego/pkg/client/orm/hints"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq" _ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
@ -529,7 +527,7 @@ func init() {
os.Exit(2) 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 { if err != nil {
panic(fmt.Sprintf("can not register database: %v", err)) panic(fmt.Sprintf("can not register database: %v", err))

View File

@ -601,7 +601,7 @@ func NewOrmUsingDB(aliasName string) Ormer {
} }
// NewOrmWithDB create a new ormer object with specify *sql.DB for query // 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...) al, err := newAliasWithDb(aliasName, driverName, db, params...)
if err != nil { if err != nil {
return nil, err return nil, err