mirror of
https://github.com/astaxie/beego.git
synced 2024-11-25 23:01:28 +00:00
orm operator args now support multi types eg: []int []*int *int, Model *Model
This commit is contained in:
parent
9047d21ec5
commit
8563000235
81
orm/db.go
81
orm/db.go
@ -949,21 +949,76 @@ func (d *dbBase) Count(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dbBase) GetOperatorSql(mi *modelInfo, operator string, args []interface{}) (string, []interface{}) {
|
func (d *dbBase) getOperatorParams(operator string, args []interface{}) (params []interface{}) {
|
||||||
params := make([]interface{}, len(args))
|
for _, arg := range args {
|
||||||
copy(params, args)
|
val := reflect.ValueOf(arg)
|
||||||
sql := ""
|
|
||||||
for i, arg := range args {
|
if arg == nil {
|
||||||
if md, ok := arg.(Modeler); ok {
|
params = append(params, arg)
|
||||||
ind := reflect.Indirect(reflect.ValueOf(md))
|
continue
|
||||||
if _, vu, exist := d.existPk(mi, ind); exist {
|
|
||||||
arg = vu
|
|
||||||
} else {
|
|
||||||
panic(fmt.Sprintf("`%s` need a valid args value", operator))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
params[i] = arg
|
|
||||||
|
kind := val.Kind()
|
||||||
|
|
||||||
|
switch kind {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
var args []interface{}
|
||||||
|
for i := 0; i < val.Len(); i++ {
|
||||||
|
v := val.Index(i)
|
||||||
|
|
||||||
|
var vu interface{}
|
||||||
|
if v.CanInterface() {
|
||||||
|
vu = v.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
if vu == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args, vu)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(args) > 0 {
|
||||||
|
p := d.getOperatorParams(operator, args)
|
||||||
|
params = append(params, p...)
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Ptr, reflect.Struct:
|
||||||
|
ind := reflect.Indirect(val)
|
||||||
|
|
||||||
|
if ind.Kind() == reflect.Struct {
|
||||||
|
typ := ind.Type()
|
||||||
|
fullName := typ.PkgPath() + "." + typ.Name()
|
||||||
|
var value interface{}
|
||||||
|
if mmi, ok := modelCache.get(fullName); ok {
|
||||||
|
if _, vu, exist := d.existPk(mmi, ind); exist {
|
||||||
|
value = vu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arg = value
|
||||||
|
|
||||||
|
if arg == nil {
|
||||||
|
panic(fmt.Sprintf("`%s` operator need a valid args value, unknown table or value `%v`", operator, val.Type()))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
arg = ind.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
params = append(params, arg)
|
||||||
|
|
||||||
|
default:
|
||||||
|
params = append(params, arg)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dbBase) GetOperatorSql(mi *modelInfo, operator string, args []interface{}) (string, []interface{}) {
|
||||||
|
sql := ""
|
||||||
|
params := d.getOperatorParams(operator, args)
|
||||||
|
|
||||||
if operator == "in" {
|
if operator == "in" {
|
||||||
marks := make([]string, len(params))
|
marks := make([]string, len(params))
|
||||||
for i, _ := range marks {
|
for i, _ := range marks {
|
||||||
|
@ -18,7 +18,7 @@ fmt.Println(o.Delete(user))
|
|||||||
o := orm.NewOrm()
|
o := orm.NewOrm()
|
||||||
user := User{Id: 1}
|
user := User{Id: 1}
|
||||||
|
|
||||||
o.Read(&user)
|
err = o.Read(&user)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
fmt.Println("查询不到")
|
fmt.Println("查询不到")
|
||||||
|
@ -16,7 +16,10 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
errLog *log.Logger
|
errLog *log.Logger
|
||||||
modelCache = &_modelCache{cache: make(map[string]*modelInfo)}
|
modelCache = &_modelCache{
|
||||||
|
cache: make(map[string]*modelInfo),
|
||||||
|
cacheByFN: make(map[string]*modelInfo),
|
||||||
|
}
|
||||||
supportTag = map[string]int{
|
supportTag = map[string]int{
|
||||||
"null": 1,
|
"null": 1,
|
||||||
"blank": 1,
|
"blank": 1,
|
||||||
@ -47,9 +50,10 @@ func init() {
|
|||||||
|
|
||||||
type _modelCache struct {
|
type _modelCache struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
orders []string
|
orders []string
|
||||||
cache map[string]*modelInfo
|
cache map[string]*modelInfo
|
||||||
done bool
|
cacheByFN map[string]*modelInfo
|
||||||
|
done bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *_modelCache) all() map[string]*modelInfo {
|
func (mc *_modelCache) all() map[string]*modelInfo {
|
||||||
@ -70,12 +74,16 @@ func (mc *_modelCache) allOrdered() []*modelInfo {
|
|||||||
|
|
||||||
func (mc *_modelCache) get(table string) (mi *modelInfo, ok bool) {
|
func (mc *_modelCache) get(table string) (mi *modelInfo, ok bool) {
|
||||||
mi, ok = mc.cache[table]
|
mi, ok = mc.cache[table]
|
||||||
|
if ok == false {
|
||||||
|
mi, ok = mc.cacheByFN[table]
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *_modelCache) set(table string, mi *modelInfo) *modelInfo {
|
func (mc *_modelCache) set(table string, mi *modelInfo) *modelInfo {
|
||||||
mii := mc.cache[table]
|
mii := mc.cache[table]
|
||||||
mc.cache[table] = mi
|
mc.cache[table] = mi
|
||||||
|
mc.cacheByFN[mi.fullName] = mi
|
||||||
if mii == nil {
|
if mii == nil {
|
||||||
mc.orders = append(mc.orders, table)
|
mc.orders = append(mc.orders, table)
|
||||||
}
|
}
|
||||||
|
@ -410,6 +410,15 @@ func TestOperators(t *testing.T) {
|
|||||||
num, err = qs.Filter("status__in", 1, 2).Count()
|
num, err = qs.Filter("status__in", 1, 2).Count()
|
||||||
throwFail(t, err)
|
throwFail(t, err)
|
||||||
throwFail(t, AssertIs(num, T_Equal, 2))
|
throwFail(t, AssertIs(num, T_Equal, 2))
|
||||||
|
|
||||||
|
num, err = qs.Filter("status__in", []int{1, 2}).Count()
|
||||||
|
throwFail(t, err)
|
||||||
|
throwFail(t, AssertIs(num, T_Equal, 2))
|
||||||
|
|
||||||
|
n1, n2 := 1, 2
|
||||||
|
num, err = qs.Filter("status__in", []*int{&n1}, &n2).Count()
|
||||||
|
throwFail(t, err)
|
||||||
|
throwFail(t, AssertIs(num, T_Equal, 2))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAll(t *testing.T) {
|
func TestAll(t *testing.T) {
|
||||||
@ -684,5 +693,49 @@ func TestDelete(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTransaction(t *testing.T) {
|
func TestTransaction(t *testing.T) {
|
||||||
|
o := NewOrm()
|
||||||
|
err := o.Begin()
|
||||||
|
throwFail(t, err)
|
||||||
|
|
||||||
|
var names = []string{"1", "2", "3"}
|
||||||
|
|
||||||
|
var user User
|
||||||
|
user.UserName = names[0]
|
||||||
|
id, err := o.Insert(&user)
|
||||||
|
throwFail(t, err)
|
||||||
|
throwFail(t, AssertIs(id, T_Large, 0))
|
||||||
|
|
||||||
|
num, err := o.QueryTable("user").Filter("user_name", "slene").Update(Params{"user_name": names[1]})
|
||||||
|
throwFail(t, err)
|
||||||
|
throwFail(t, AssertIs(num, T_Large, 0))
|
||||||
|
|
||||||
|
switch o.Driver().Type() {
|
||||||
|
case DR_MySQL:
|
||||||
|
id, err := o.Raw("INSERT INTO user (user_name) VALUES (?)", names[2]).Exec()
|
||||||
|
throwFail(t, err)
|
||||||
|
throwFail(t, AssertIs(id, T_Large, 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
err = o.Rollback()
|
||||||
|
throwFail(t, err)
|
||||||
|
|
||||||
|
num, err = o.QueryTable("user").Filter("user_name__in", &user).Count()
|
||||||
|
throwFail(t, err)
|
||||||
|
throwFail(t, AssertIs(num, T_Equal, 0))
|
||||||
|
|
||||||
|
err = o.Begin()
|
||||||
|
throwFail(t, err)
|
||||||
|
|
||||||
|
user.UserName = "commit"
|
||||||
|
id, err = o.Insert(&user)
|
||||||
|
throwFail(t, err)
|
||||||
|
throwFail(t, AssertIs(id, T_Large, 0))
|
||||||
|
|
||||||
|
o.Commit()
|
||||||
|
throwFail(t, err)
|
||||||
|
|
||||||
|
num, err = o.QueryTable("user").Filter("user_name", "commit").Delete()
|
||||||
|
throwFail(t, err)
|
||||||
|
throwFail(t, AssertIs(num, T_Equal, 1))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user