mirror of
https://github.com/astaxie/beego.git
synced 2025-06-12 17:10:40 +00:00
Merge branch 'develop-2.0' into frt/proposal_4105
This commit is contained in:
@ -142,6 +142,12 @@ func (d *commandSyncDb) Run() error {
|
||||
}
|
||||
|
||||
for i, mi := range modelCache.allOrdered() {
|
||||
|
||||
if !isApplicableTableForDB(mi.addrField, d.al.Name) {
|
||||
fmt.Printf("table `%s` is not applicable to database '%s'\n", mi.table, d.al.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
if tables[mi.table] {
|
||||
if !d.noInfo {
|
||||
fmt.Printf("table `%s` already exists, skip\n", mi.table)
|
||||
|
@ -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,31 +400,48 @@ func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...utils.KV
|
||||
|
||||
detectTZ(al)
|
||||
|
||||
kvs.IfContains(hints.KeyMaxIdleConnections, func(value interface{}) {
|
||||
if m, ok := value.(int); ok {
|
||||
SetMaxIdleConns(al, m)
|
||||
}
|
||||
}).IfContains(hints.KeyMaxOpenConnections, func(value interface{}) {
|
||||
if m, ok := value.(int); ok {
|
||||
SetMaxOpenConns(al, m)
|
||||
}
|
||||
}).IfContains(hints.KeyConnMaxLifetime, func(value interface{}) {
|
||||
if m, ok := value.(time.Duration); ok {
|
||||
SetConnMaxLifetime(al, m)
|
||||
}
|
||||
})
|
||||
|
||||
return al, nil
|
||||
}
|
||||
|
||||
// SetMaxIdleConns Change the max idle conns for *sql.DB, use specify database alias name
|
||||
// Deprecated you should not use this, we will remove it in the future
|
||||
func SetMaxIdleConns(aliasName string, maxIdleConns int) {
|
||||
al := getDbAlias(aliasName)
|
||||
al.SetMaxIdleConns(maxIdleConns)
|
||||
}
|
||||
|
||||
// SetMaxOpenConns Change the max open conns for *sql.DB, use specify database alias name
|
||||
// Deprecated you should not use this, we will remove it in the future
|
||||
func SetMaxOpenConns(aliasName string, maxOpenConns int) {
|
||||
al := getDbAlias(aliasName)
|
||||
al.SetMaxIdleConns(maxOpenConns)
|
||||
}
|
||||
|
||||
// SetMaxIdleConns Change the max idle conns for *sql.DB, use specify database alias name
|
||||
func (al *alias) SetMaxIdleConns(maxIdleConns int) {
|
||||
al.MaxIdleConns = maxIdleConns
|
||||
al.DB.DB.SetMaxIdleConns(maxIdleConns)
|
||||
}
|
||||
|
||||
// SetMaxOpenConns Change the max open conns for *sql.DB, use specify database alias name
|
||||
func (al *alias) SetMaxOpenConns(maxOpenConns int) {
|
||||
al.MaxOpenConns = maxOpenConns
|
||||
al.DB.DB.SetMaxOpenConns(maxOpenConns)
|
||||
}
|
||||
|
||||
func (al *alias) SetConnMaxLifetime(lifeTime time.Duration) {
|
||||
al.ConnMaxLifetime = lifeTime
|
||||
al.DB.DB.SetConnMaxLifetime(lifeTime)
|
||||
}
|
||||
|
||||
// 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
|
||||
@ -476,23 +494,6 @@ func SetDataBaseTZ(aliasName string, tz *time.Location) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetMaxIdleConns Change the max idle conns for *sql.DB, use specify database alias name
|
||||
func SetMaxIdleConns(al *alias, maxIdleConns int) {
|
||||
al.MaxIdleConns = maxIdleConns
|
||||
al.DB.DB.SetMaxIdleConns(maxIdleConns)
|
||||
}
|
||||
|
||||
// SetMaxOpenConns Change the max open conns for *sql.DB, use specify database alias name
|
||||
func SetMaxOpenConns(al *alias, maxOpenConns int) {
|
||||
al.MaxOpenConns = maxOpenConns
|
||||
al.DB.DB.SetMaxOpenConns(maxOpenConns)
|
||||
}
|
||||
|
||||
func SetConnMaxLifetime(al *alias, lifeTime time.Duration) {
|
||||
al.ConnMaxLifetime = lifeTime
|
||||
al.DB.DB.SetConnMaxLifetime(lifeTime)
|
||||
}
|
||||
|
||||
// GetDB Get *sql.DB from registered database by db alias name.
|
||||
// Use "default" as alias name if you not set.
|
||||
func GetDB(aliasNames ...string) (*sql.DB, error) {
|
||||
@ -553,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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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...)
|
||||
|
@ -31,7 +31,7 @@ type Unique struct {
|
||||
Columns []*Column
|
||||
}
|
||||
|
||||
//Column struct defines a single column of a table
|
||||
// Column struct defines a single column of a table
|
||||
type Column struct {
|
||||
Name string
|
||||
Inc string
|
||||
@ -84,7 +84,7 @@ func (m *Migration) NewCol(name string) *Column {
|
||||
return col
|
||||
}
|
||||
|
||||
//PriCol creates a new primary column and attaches it to m struct
|
||||
// PriCol creates a new primary column and attaches it to m struct
|
||||
func (m *Migration) PriCol(name string) *Column {
|
||||
col := &Column{Name: name}
|
||||
m.AddColumns(col)
|
||||
@ -92,7 +92,7 @@ func (m *Migration) PriCol(name string) *Column {
|
||||
return col
|
||||
}
|
||||
|
||||
//UniCol creates / appends columns to specified unique key and attaches it to m struct
|
||||
// UniCol creates / appends columns to specified unique key and attaches it to m struct
|
||||
func (m *Migration) UniCol(uni, name string) *Column {
|
||||
col := &Column{Name: name}
|
||||
m.AddColumns(col)
|
||||
@ -114,7 +114,7 @@ func (m *Migration) UniCol(uni, name string) *Column {
|
||||
return col
|
||||
}
|
||||
|
||||
//ForeignCol creates a new foreign column and returns the instance of column
|
||||
// ForeignCol creates a new foreign column and returns the instance of column
|
||||
func (m *Migration) ForeignCol(colname, foreigncol, foreigntable string) (foreign *Foreign) {
|
||||
|
||||
foreign = &Foreign{ForeignColumn: foreigncol, ForeignTable: foreigntable}
|
||||
@ -123,25 +123,25 @@ func (m *Migration) ForeignCol(colname, foreigncol, foreigntable string) (foreig
|
||||
return foreign
|
||||
}
|
||||
|
||||
//SetOnDelete sets the on delete of foreign
|
||||
// SetOnDelete sets the on delete of foreign
|
||||
func (foreign *Foreign) SetOnDelete(del string) *Foreign {
|
||||
foreign.OnDelete = "ON DELETE" + del
|
||||
return foreign
|
||||
}
|
||||
|
||||
//SetOnUpdate sets the on update of foreign
|
||||
// SetOnUpdate sets the on update of foreign
|
||||
func (foreign *Foreign) SetOnUpdate(update string) *Foreign {
|
||||
foreign.OnUpdate = "ON UPDATE" + update
|
||||
return foreign
|
||||
}
|
||||
|
||||
//Remove marks the columns to be removed.
|
||||
//it allows reverse m to create the column.
|
||||
// Remove marks the columns to be removed.
|
||||
// it allows reverse m to create the column.
|
||||
func (c *Column) Remove() {
|
||||
c.remove = true
|
||||
}
|
||||
|
||||
//SetAuto enables auto_increment of column (can be used once)
|
||||
// SetAuto enables auto_increment of column (can be used once)
|
||||
func (c *Column) SetAuto(inc bool) *Column {
|
||||
if inc {
|
||||
c.Inc = "auto_increment"
|
||||
@ -149,7 +149,7 @@ func (c *Column) SetAuto(inc bool) *Column {
|
||||
return c
|
||||
}
|
||||
|
||||
//SetNullable sets the column to be null
|
||||
// SetNullable sets the column to be null
|
||||
func (c *Column) SetNullable(null bool) *Column {
|
||||
if null {
|
||||
c.Null = ""
|
||||
@ -160,13 +160,13 @@ func (c *Column) SetNullable(null bool) *Column {
|
||||
return c
|
||||
}
|
||||
|
||||
//SetDefault sets the default value, prepend with "DEFAULT "
|
||||
// SetDefault sets the default value, prepend with "DEFAULT "
|
||||
func (c *Column) SetDefault(def string) *Column {
|
||||
c.Default = "DEFAULT " + def
|
||||
return c
|
||||
}
|
||||
|
||||
//SetUnsigned sets the column to be unsigned int
|
||||
// SetUnsigned sets the column to be unsigned int
|
||||
func (c *Column) SetUnsigned(unsign bool) *Column {
|
||||
if unsign {
|
||||
c.Unsign = "UNSIGNED"
|
||||
@ -174,13 +174,13 @@ func (c *Column) SetUnsigned(unsign bool) *Column {
|
||||
return c
|
||||
}
|
||||
|
||||
//SetDataType sets the dataType of the column
|
||||
// SetDataType sets the dataType of the column
|
||||
func (c *Column) SetDataType(dataType string) *Column {
|
||||
c.DataType = dataType
|
||||
return c
|
||||
}
|
||||
|
||||
//SetOldNullable allows reverting to previous nullable on reverse ms
|
||||
// SetOldNullable allows reverting to previous nullable on reverse ms
|
||||
func (c *RenameColumn) SetOldNullable(null bool) *RenameColumn {
|
||||
if null {
|
||||
c.OldNull = ""
|
||||
@ -191,13 +191,13 @@ func (c *RenameColumn) SetOldNullable(null bool) *RenameColumn {
|
||||
return c
|
||||
}
|
||||
|
||||
//SetOldDefault allows reverting to previous default on reverse ms
|
||||
// SetOldDefault allows reverting to previous default on reverse ms
|
||||
func (c *RenameColumn) SetOldDefault(def string) *RenameColumn {
|
||||
c.OldDefault = def
|
||||
return c
|
||||
}
|
||||
|
||||
//SetOldUnsigned allows reverting to previous unsgined on reverse ms
|
||||
// SetOldUnsigned allows reverting to previous unsgined on reverse ms
|
||||
func (c *RenameColumn) SetOldUnsigned(unsign bool) *RenameColumn {
|
||||
if unsign {
|
||||
c.OldUnsign = "UNSIGNED"
|
||||
@ -205,19 +205,19 @@ func (c *RenameColumn) SetOldUnsigned(unsign bool) *RenameColumn {
|
||||
return c
|
||||
}
|
||||
|
||||
//SetOldDataType allows reverting to previous datatype on reverse ms
|
||||
// SetOldDataType allows reverting to previous datatype on reverse ms
|
||||
func (c *RenameColumn) SetOldDataType(dataType string) *RenameColumn {
|
||||
c.OldDataType = dataType
|
||||
return c
|
||||
}
|
||||
|
||||
//SetPrimary adds the columns to the primary key (can only be used any number of times in only one m)
|
||||
// SetPrimary adds the columns to the primary key (can only be used any number of times in only one m)
|
||||
func (c *Column) SetPrimary(m *Migration) *Column {
|
||||
m.Primary = append(m.Primary, c)
|
||||
return c
|
||||
}
|
||||
|
||||
//AddColumnsToUnique adds the columns to Unique Struct
|
||||
// AddColumnsToUnique adds the columns to Unique Struct
|
||||
func (unique *Unique) AddColumnsToUnique(columns ...*Column) *Unique {
|
||||
|
||||
unique.Columns = append(unique.Columns, columns...)
|
||||
@ -225,7 +225,7 @@ func (unique *Unique) AddColumnsToUnique(columns ...*Column) *Unique {
|
||||
return unique
|
||||
}
|
||||
|
||||
//AddColumns adds columns to m struct
|
||||
// AddColumns adds columns to m struct
|
||||
func (m *Migration) AddColumns(columns ...*Column) *Migration {
|
||||
|
||||
m.Columns = append(m.Columns, columns...)
|
||||
@ -233,38 +233,38 @@ func (m *Migration) AddColumns(columns ...*Column) *Migration {
|
||||
return m
|
||||
}
|
||||
|
||||
//AddPrimary adds the column to primary in m struct
|
||||
// AddPrimary adds the column to primary in m struct
|
||||
func (m *Migration) AddPrimary(primary *Column) *Migration {
|
||||
m.Primary = append(m.Primary, primary)
|
||||
return m
|
||||
}
|
||||
|
||||
//AddUnique adds the column to unique in m struct
|
||||
// AddUnique adds the column to unique in m struct
|
||||
func (m *Migration) AddUnique(unique *Unique) *Migration {
|
||||
m.Uniques = append(m.Uniques, unique)
|
||||
return m
|
||||
}
|
||||
|
||||
//AddForeign adds the column to foreign in m struct
|
||||
// AddForeign adds the column to foreign in m struct
|
||||
func (m *Migration) AddForeign(foreign *Foreign) *Migration {
|
||||
m.Foreigns = append(m.Foreigns, foreign)
|
||||
return m
|
||||
}
|
||||
|
||||
//AddIndex adds the column to index in m struct
|
||||
// AddIndex adds the column to index in m struct
|
||||
func (m *Migration) AddIndex(index *Index) *Migration {
|
||||
m.Indexes = append(m.Indexes, index)
|
||||
return m
|
||||
}
|
||||
|
||||
//RenameColumn allows renaming of columns
|
||||
// RenameColumn allows renaming of columns
|
||||
func (m *Migration) RenameColumn(from, to string) *RenameColumn {
|
||||
rename := &RenameColumn{OldName: from, NewName: to}
|
||||
m.Renames = append(m.Renames, rename)
|
||||
return rename
|
||||
}
|
||||
|
||||
//GetSQL returns the generated sql depending on ModifyType
|
||||
// GetSQL returns the generated sql depending on ModifyType
|
||||
func (m *Migration) GetSQL() (sql string) {
|
||||
sql = ""
|
||||
switch m.ModifyType {
|
||||
|
@ -442,7 +442,7 @@ func (mc *_modelCache) getDbDropSQL(al *alias) (queries []string, err error) {
|
||||
for _, mi := range mc.allOrdered() {
|
||||
queries = append(queries, fmt.Sprintf(`DROP TABLE IF EXISTS %s%s%s`, Q, mi.table, Q))
|
||||
}
|
||||
return queries,nil
|
||||
return queries, nil
|
||||
}
|
||||
|
||||
//getDbCreateSQL get database scheme creation sql queries
|
||||
|
@ -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))
|
||||
|
@ -107,6 +107,18 @@ func getTableUnique(val reflect.Value) [][]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
// get whether the table needs to be created for the database alias
|
||||
func isApplicableTableForDB(val reflect.Value, db string) bool {
|
||||
fun := val.MethodByName("IsApplicableTableForDB")
|
||||
if fun.IsValid() {
|
||||
vals := fun.Call([]reflect.Value{reflect.ValueOf(db)})
|
||||
if len(vals) > 0 && vals[0].Kind() == reflect.Bool {
|
||||
return vals[0].Bool()
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// get snaked column name
|
||||
func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col string) string {
|
||||
column := col
|
||||
|
35
pkg/client/orm/models_utils_test.go
Normal file
35
pkg/client/orm/models_utils_test.go
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright 2020
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type NotApplicableModel struct {
|
||||
Id int
|
||||
}
|
||||
|
||||
func (n *NotApplicableModel) IsApplicableTableForDB(db string) bool {
|
||||
return db == "default"
|
||||
}
|
||||
|
||||
func Test_IsApplicableTableForDB(t *testing.T) {
|
||||
assert.False(t, isApplicableTableForDB(reflect.ValueOf(&NotApplicableModel{}), "defa"))
|
||||
assert.True(t, isApplicableTableForDB(reflect.ValueOf(&NotApplicableModel{}), "default"))
|
||||
}
|
@ -311,9 +311,7 @@ func (o *ormBase) LoadRelated(md interface{}, name string, args ...utils.KV) (in
|
||||
return o.LoadRelatedWithCtx(context.Background(), md, name, args...)
|
||||
}
|
||||
func (o *ormBase) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...utils.KV) (int64, error) {
|
||||
_, fi, ind, qseter := o.queryRelated(md, name)
|
||||
|
||||
qs := qseter.(*querySet)
|
||||
_, fi, ind, qs := o.queryRelated(md, name)
|
||||
|
||||
var relDepth int
|
||||
var limit, offset int64
|
||||
@ -377,7 +375,7 @@ func (o *ormBase) LoadRelatedWithCtx(ctx context.Context, md interface{}, name s
|
||||
}
|
||||
|
||||
// get QuerySeter for related models to md model
|
||||
func (o *ormBase) queryRelated(md interface{}, name string) (*modelInfo, *fieldInfo, reflect.Value, QuerySeter) {
|
||||
func (o *ormBase) queryRelated(md interface{}, name string) (*modelInfo, *fieldInfo, reflect.Value, *querySet) {
|
||||
mi, ind := o.getMiInd(md, true)
|
||||
fi := o.getFieldInfo(mi, name)
|
||||
|
||||
@ -616,7 +614,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
|
||||
|
@ -330,6 +330,8 @@ func (o *rawSet) QueryRow(containers ...interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
structTagMap := make(map[reflect.StructTag]map[string]string)
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
if rows.Next() {
|
||||
@ -396,7 +398,12 @@ func (o *rawSet) QueryRow(containers ...interface{}) error {
|
||||
recursiveSetField(f)
|
||||
}
|
||||
|
||||
_, tags := parseStructTag(fe.Tag.Get(defaultStructTagName))
|
||||
// thanks @Gazeboxu.
|
||||
tags := structTagMap[fe.Tag]
|
||||
if tags == nil {
|
||||
_, tags = parseStructTag(fe.Tag.Get(defaultStructTagName))
|
||||
structTagMap[fe.Tag] = tags
|
||||
}
|
||||
var col string
|
||||
if col = tags["column"]; col == "" {
|
||||
col = nameStrategyMap[nameStrategy](fe.Name)
|
||||
|
@ -75,6 +75,11 @@ type TableUniqueI interface {
|
||||
TableUnique() [][]string
|
||||
}
|
||||
|
||||
// IsApplicableTableForDB if return false, we won't create table to this db
|
||||
type IsApplicableTableForDB interface {
|
||||
IsApplicableTableForDB(db string) bool
|
||||
}
|
||||
|
||||
// Driver define database driver
|
||||
type Driver interface {
|
||||
Name() string
|
||||
|
Reference in New Issue
Block a user