mirror of
https://github.com/astaxie/beego.git
synced 2025-06-11 20:10:40 +00:00
Resolve conflict
This commit is contained in:
@ -75,3 +75,13 @@ func TestRegisterDataBase_MaxStmtCacheSize841(t *testing.T) {
|
||||
assert.Equal(t, al.DB.stmtDecoratorsLimit, 841)
|
||||
}
|
||||
|
||||
|
||||
func TestDBCache(t *testing.T) {
|
||||
dataBaseCache.add("test1", &alias{})
|
||||
dataBaseCache.add("default", &alias{})
|
||||
al := dataBaseCache.getDefault()
|
||||
assert.NotNil(t, al)
|
||||
al, ok := dataBaseCache.get("test1")
|
||||
assert.NotNil(t, al)
|
||||
assert.True(t, ok)
|
||||
}
|
||||
|
62
pkg/orm/model_utils_test.go
Normal file
62
pkg/orm/model_utils_test.go
Normal file
@ -0,0 +1,62 @@
|
||||
// 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 (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type Interface struct {
|
||||
Id int
|
||||
Name string
|
||||
|
||||
Index1 string
|
||||
Index2 string
|
||||
|
||||
Unique1 string
|
||||
Unique2 string
|
||||
}
|
||||
|
||||
func (i *Interface) TableIndex() [][]string {
|
||||
return [][]string{{"index1"}, {"index2"}}
|
||||
}
|
||||
|
||||
func (i *Interface) TableUnique() [][]string {
|
||||
return [][]string{{"unique1"}, {"unique2"}}
|
||||
}
|
||||
|
||||
func (i *Interface) TableName() string {
|
||||
return "INTERFACE_"
|
||||
}
|
||||
|
||||
func (i *Interface) TableEngine() string {
|
||||
return "innodb"
|
||||
}
|
||||
|
||||
func TestDbBase_GetTables(t *testing.T) {
|
||||
RegisterModel(&Interface{})
|
||||
mi, ok := modelCache.get("INTERFACE_")
|
||||
assert.True(t, ok)
|
||||
assert.NotNil(t, mi)
|
||||
|
||||
engine := getTableEngine(mi.addrField)
|
||||
assert.Equal(t, "innodb", engine)
|
||||
uniques := getTableUnique(mi.addrField)
|
||||
assert.Equal(t, [][]string{{"unique1"}, {"unique2"}}, uniques)
|
||||
indexes := getTableIndex(mi.addrField)
|
||||
assert.Equal(t, [][]string{{"index1"}, {"index2"}}, indexes)
|
||||
}
|
@ -29,7 +29,7 @@ type modelInfo struct {
|
||||
model interface{}
|
||||
fields *fields
|
||||
manual bool
|
||||
addrField reflect.Value //store the original struct value
|
||||
addrField reflect.Value // store the original struct value
|
||||
uniques []string
|
||||
isThrough bool
|
||||
}
|
||||
|
@ -305,6 +305,7 @@ func (o *ormBase) QueryM2MWithCtx(ctx context.Context, md interface{}, name stri
|
||||
func (o *ormBase) LoadRelated(md interface{}, name string, args ...interface{}) (int64, error) {
|
||||
return o.LoadRelatedWithCtx(context.Background(), md, name, args...)
|
||||
}
|
||||
|
||||
func (o *ormBase) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...interface{}) (int64, error) {
|
||||
_, fi, ind, qseter := o.queryRelated(md, name)
|
||||
|
||||
@ -366,21 +367,6 @@ func (o *ormBase) LoadRelatedWithCtx(ctx context.Context, md interface{}, name s
|
||||
return nums, err
|
||||
}
|
||||
|
||||
// return a QuerySeter for related models to md model.
|
||||
// it can do all, update, delete in QuerySeter.
|
||||
// example:
|
||||
// qs := orm.QueryRelated(post,"Tag")
|
||||
// qs.All(&[]*Tag{})
|
||||
//
|
||||
func (o *ormBase) QueryRelated(md interface{}, name string) QuerySeter {
|
||||
return o.QueryRelatedWithCtx(context.Background(), md, name)
|
||||
}
|
||||
func (o *ormBase) QueryRelatedWithCtx(ctx context.Context, md interface{}, name string) QuerySeter {
|
||||
// is this api needed ?
|
||||
_, _, _, qs := o.queryRelated(md, name)
|
||||
return qs
|
||||
}
|
||||
|
||||
// get QuerySeter for related models to md model
|
||||
func (o *ormBase) queryRelated(md interface{}, name string) (*modelInfo, *fieldInfo, reflect.Value, QuerySeter) {
|
||||
mi, ind := o.getMiInd(md, true)
|
||||
@ -591,10 +577,13 @@ func (t *txOrm) Rollback() error {
|
||||
// NewOrm create new orm
|
||||
func NewOrm() Ormer {
|
||||
BootStrap() // execute only once
|
||||
return NewOrmUsingDB(`default`)
|
||||
}
|
||||
|
||||
// NewOrmUsingDB create new orm with the name
|
||||
func NewOrmUsingDB(aliasName string) Ormer {
|
||||
o := new(orm)
|
||||
name := `default`
|
||||
if al, ok := dataBaseCache.get(name); ok {
|
||||
if al, ok := dataBaseCache.get(aliasName); ok {
|
||||
o.alias = al
|
||||
if Debug {
|
||||
o.db = newDbQueryLog(al, al.DB)
|
||||
@ -602,9 +591,8 @@ func NewOrm() Ormer {
|
||||
o.db = al.DB
|
||||
}
|
||||
} else {
|
||||
panic(fmt.Errorf("<Ormer.Using> unknown db alias name `%s`", name))
|
||||
panic(fmt.Errorf("<Ormer.Using> unknown db alias name `%s`", aliasName))
|
||||
}
|
||||
|
||||
return o
|
||||
}
|
||||
|
||||
|
@ -297,16 +297,13 @@ func TestDataTypes(t *testing.T) {
|
||||
vu := e.Interface()
|
||||
switch name {
|
||||
case "Date":
|
||||
vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDate)
|
||||
value = value.(time.Time).In(DefaultTimeLoc).Format(testDate)
|
||||
case "DateTime":
|
||||
vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
|
||||
value = value.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
|
||||
case "Time":
|
||||
vu = vu.(time.Time).In(DefaultTimeLoc).Format(testTime)
|
||||
value = value.(time.Time).In(DefaultTimeLoc).Format(testTime)
|
||||
assert.True(t, vu.(time.Time).In(DefaultTimeLoc).Sub(value.(time.Time).In(DefaultTimeLoc)) <= time.Second)
|
||||
break
|
||||
default:
|
||||
assert.Equal(t, value, vu)
|
||||
}
|
||||
throwFail(t, AssertIs(vu == value, true), value, vu)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1662,18 +1659,14 @@ func TestRawQueryRow(t *testing.T) {
|
||||
switch col {
|
||||
case "id":
|
||||
throwFail(t, AssertIs(id, 1))
|
||||
break
|
||||
case "time":
|
||||
v = v.(time.Time).In(DefaultTimeLoc)
|
||||
value := dataValues[col].(time.Time).In(DefaultTimeLoc)
|
||||
throwFail(t, AssertIs(v, value, testTime))
|
||||
case "date":
|
||||
v = v.(time.Time).In(DefaultTimeLoc)
|
||||
value := dataValues[col].(time.Time).In(DefaultTimeLoc)
|
||||
throwFail(t, AssertIs(v, value, testDate))
|
||||
case "datetime":
|
||||
v = v.(time.Time).In(DefaultTimeLoc)
|
||||
value := dataValues[col].(time.Time).In(DefaultTimeLoc)
|
||||
throwFail(t, AssertIs(v, value, testDateTime))
|
||||
assert.True(t, v.(time.Time).Sub(value) <= time.Second)
|
||||
break
|
||||
default:
|
||||
throwFail(t, AssertIs(v, dataValues[col]))
|
||||
}
|
||||
@ -1746,16 +1739,13 @@ func TestQueryRows(t *testing.T) {
|
||||
vu := e.Interface()
|
||||
switch name {
|
||||
case "Time":
|
||||
vu = vu.(time.Time).In(DefaultTimeLoc).Format(testTime)
|
||||
value = value.(time.Time).In(DefaultTimeLoc).Format(testTime)
|
||||
case "Date":
|
||||
vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDate)
|
||||
value = value.(time.Time).In(DefaultTimeLoc).Format(testDate)
|
||||
case "DateTime":
|
||||
vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
|
||||
value = value.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
|
||||
assert.True(t, vu.(time.Time).In(DefaultTimeLoc).Sub(value.(time.Time).In(DefaultTimeLoc)) <= time.Second)
|
||||
break
|
||||
default:
|
||||
assert.Equal(t, value, vu)
|
||||
}
|
||||
throwFail(t, AssertIs(vu == value, true), value, vu)
|
||||
}
|
||||
|
||||
var datas2 []Data
|
||||
@ -1773,16 +1763,14 @@ func TestQueryRows(t *testing.T) {
|
||||
vu := e.Interface()
|
||||
switch name {
|
||||
case "Time":
|
||||
vu = vu.(time.Time).In(DefaultTimeLoc).Format(testTime)
|
||||
value = value.(time.Time).In(DefaultTimeLoc).Format(testTime)
|
||||
case "Date":
|
||||
vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDate)
|
||||
value = value.(time.Time).In(DefaultTimeLoc).Format(testDate)
|
||||
case "DateTime":
|
||||
vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
|
||||
value = value.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
|
||||
assert.True(t, vu.(time.Time).In(DefaultTimeLoc).Sub(value.(time.Time).In(DefaultTimeLoc)) <= time.Second)
|
||||
break
|
||||
default:
|
||||
assert.Equal(t, value, vu)
|
||||
}
|
||||
throwFail(t, AssertIs(vu == value, true), value, vu)
|
||||
|
||||
}
|
||||
|
||||
var ids []int
|
||||
@ -2193,8 +2181,8 @@ func TestInLine(t *testing.T) {
|
||||
|
||||
throwFail(t, AssertIs(il.Name, name))
|
||||
throwFail(t, AssertIs(il.Email, email))
|
||||
throwFail(t, AssertIs(il.Created.In(DefaultTimeLoc), inline.Created.In(DefaultTimeLoc), testDate))
|
||||
throwFail(t, AssertIs(il.Updated.In(DefaultTimeLoc), inline.Updated.In(DefaultTimeLoc), testDateTime))
|
||||
assert.True(t, il.Created.In(DefaultTimeLoc).Sub(inline.Created.In(DefaultTimeLoc)) <= time.Second)
|
||||
assert.True(t, il.Updated.In(DefaultTimeLoc).Sub(inline.Updated.In(DefaultTimeLoc)) <= time.Second)
|
||||
}
|
||||
|
||||
func TestInLineOneToOne(t *testing.T) {
|
||||
|
@ -21,6 +21,58 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// TableNaming is usually used by model
|
||||
// when you custom your table name, please implement this interfaces
|
||||
// for example:
|
||||
// type User struct {
|
||||
// ...
|
||||
// }
|
||||
// func (u *User) TableName() string {
|
||||
// return "USER_TABLE"
|
||||
// }
|
||||
type TableNameI interface {
|
||||
TableName() string
|
||||
}
|
||||
|
||||
// TableEngineI is usually used by model
|
||||
// when you want to use specific engine, like myisam, you can implement this interface
|
||||
// for example:
|
||||
// type User struct {
|
||||
// ...
|
||||
// }
|
||||
// func (u *User) TableEngine() string {
|
||||
// return "myisam"
|
||||
// }
|
||||
type TableEngineI interface {
|
||||
TableEngine() string
|
||||
}
|
||||
|
||||
// TableIndexI is usually used by model
|
||||
// when you want to create indexes, you can implement this interface
|
||||
// for example:
|
||||
// type User struct {
|
||||
// ...
|
||||
// }
|
||||
// func (u *User) TableIndex() [][]string {
|
||||
// return [][]string{{"Name"}}
|
||||
// }
|
||||
type TableIndexI interface {
|
||||
TableIndex() [][]string
|
||||
}
|
||||
|
||||
// TableUniqueI is usually used by model
|
||||
// when you want to create unique indexes, you can implement this interface
|
||||
// for example:
|
||||
// type User struct {
|
||||
// ...
|
||||
// }
|
||||
// func (u *User) TableUnique() [][]string {
|
||||
// return [][]string{{"Email"}}
|
||||
// }
|
||||
type TableUniqueI interface {
|
||||
TableUnique() [][]string
|
||||
}
|
||||
|
||||
// Driver define database driver
|
||||
type Driver interface {
|
||||
Name() string
|
||||
@ -145,9 +197,6 @@ type DQL interface {
|
||||
QueryTable(ptrStructOrTableName interface{}) QuerySeter
|
||||
QueryTableWithCtx(ctx context.Context, ptrStructOrTableName interface{}) QuerySeter
|
||||
|
||||
// switch to another registered database driver by given name.
|
||||
// Using(name string) error
|
||||
|
||||
DBStats() *sql.DBStats
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user