mirror of
https://github.com/astaxie/beego.git
synced 2024-11-22 14:10:54 +00:00
orm add atomic set value
This commit is contained in:
parent
278f8eb13e
commit
bf3830b6f0
31
orm/db.go
31
orm/db.go
@ -382,17 +382,38 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
|
|||||||
|
|
||||||
join := tables.getJoinSql()
|
join := tables.getJoinSql()
|
||||||
|
|
||||||
var query string
|
var query, T, cols string
|
||||||
|
|
||||||
Q := d.ins.TableQuote()
|
Q := d.ins.TableQuote()
|
||||||
|
|
||||||
if d.ins.SupportUpdateJoin() {
|
if d.ins.SupportUpdateJoin() {
|
||||||
cols := strings.Join(columns, fmt.Sprintf("%s = ?, T0.%s", Q, Q))
|
T = "T0."
|
||||||
query = fmt.Sprintf("UPDATE %s%s%s T0 %sSET T0.%s%s%s = ? %s", Q, mi.table, Q, join, Q, cols, Q, where)
|
}
|
||||||
|
|
||||||
|
for i, v := range columns {
|
||||||
|
col := fmt.Sprintf("%s%s%s%s", T, Q, v, Q)
|
||||||
|
if c, ok := values[i].(colValue); ok {
|
||||||
|
switch c.opt {
|
||||||
|
case Col_Add:
|
||||||
|
cols += col + " = " + col + " + ? "
|
||||||
|
case Col_Minus:
|
||||||
|
cols += col + " = " + col + " - ? "
|
||||||
|
case Col_Multiply:
|
||||||
|
cols += col + " = " + col + " * ? "
|
||||||
|
case Col_Except:
|
||||||
|
cols += col + " = " + col + " / ? "
|
||||||
|
}
|
||||||
|
values[i] = c.value
|
||||||
|
} else {
|
||||||
|
cols += col + " = ? "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.ins.SupportUpdateJoin() {
|
||||||
|
query = fmt.Sprintf("UPDATE %s%s%s T0 %sSET %s%s", Q, mi.table, Q, join, cols, where)
|
||||||
} else {
|
} else {
|
||||||
cols := strings.Join(columns, fmt.Sprintf("%s = ?, %s", Q, Q))
|
|
||||||
supQuery := fmt.Sprintf("SELECT T0.%s%s%s FROM %s%s%s T0 %s%s", Q, mi.fields.pk.column, Q, Q, mi.table, Q, join, where)
|
supQuery := fmt.Sprintf("SELECT T0.%s%s%s FROM %s%s%s T0 %s%s", Q, mi.fields.pk.column, Q, Q, mi.table, Q, join, where)
|
||||||
query = fmt.Sprintf("UPDATE %s%s%s SET %s%s%s = ? WHERE %s%s%s IN ( %s )", Q, mi.table, Q, Q, cols, Q, Q, mi.fields.pk.column, Q, supQuery)
|
query = fmt.Sprintf("UPDATE %s%s%s SET %sWHERE %s%s%s IN ( %s )", Q, mi.table, Q, cols, Q, mi.fields.pk.column, Q, supQuery)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.ins.ReplaceMarks(&query)
|
d.ins.ReplaceMarks(&query)
|
||||||
|
@ -77,6 +77,7 @@ type User struct {
|
|||||||
Profile *Profile `orm:"null;rel(one);on_delete(set_null)"`
|
Profile *Profile `orm:"null;rel(one);on_delete(set_null)"`
|
||||||
Posts []*Post `orm:"reverse(many)" json:"-"`
|
Posts []*Post `orm:"reverse(many)" json:"-"`
|
||||||
ShouldSkip string `orm:"-"`
|
ShouldSkip string `orm:"-"`
|
||||||
|
Nums int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) TableIndex() [][]string {
|
func (u *User) TableIndex() [][]string {
|
||||||
|
@ -4,6 +4,36 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type colValue struct {
|
||||||
|
value int64
|
||||||
|
opt operator
|
||||||
|
}
|
||||||
|
|
||||||
|
type operator int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Col_Add operator = iota
|
||||||
|
Col_Minus
|
||||||
|
Col_Multiply
|
||||||
|
Col_Except
|
||||||
|
)
|
||||||
|
|
||||||
|
func ColValue(opt operator, value interface{}) interface{} {
|
||||||
|
switch opt {
|
||||||
|
case Col_Add, Col_Minus, Col_Multiply, Col_Except:
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("orm.ColValue wrong operator"))
|
||||||
|
}
|
||||||
|
v, err := StrTo(ToStr(value)).Int64()
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("orm.ColValue doesn't support non string/numeric type, %s", err))
|
||||||
|
}
|
||||||
|
var val colValue
|
||||||
|
val.value = v
|
||||||
|
val.opt = opt
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
type querySet struct {
|
type querySet struct {
|
||||||
mi *modelInfo
|
mi *modelInfo
|
||||||
cond *Condition
|
cond *Condition
|
||||||
|
@ -1230,6 +1230,35 @@ func TestUpdate(t *testing.T) {
|
|||||||
})
|
})
|
||||||
throwFail(t, err)
|
throwFail(t, err)
|
||||||
throwFail(t, AssertIs(num, 1))
|
throwFail(t, AssertIs(num, 1))
|
||||||
|
|
||||||
|
num, err = qs.Filter("user_name", "slene").Update(Params{
|
||||||
|
"Nums": ColValue(Col_Add, 100),
|
||||||
|
})
|
||||||
|
throwFail(t, err)
|
||||||
|
throwFail(t, AssertIs(num, 1))
|
||||||
|
|
||||||
|
num, err = qs.Filter("user_name", "slene").Update(Params{
|
||||||
|
"Nums": ColValue(Col_Minus, 50),
|
||||||
|
})
|
||||||
|
throwFail(t, err)
|
||||||
|
throwFail(t, AssertIs(num, 1))
|
||||||
|
|
||||||
|
num, err = qs.Filter("user_name", "slene").Update(Params{
|
||||||
|
"Nums": ColValue(Col_Multiply, 3),
|
||||||
|
})
|
||||||
|
throwFail(t, err)
|
||||||
|
throwFail(t, AssertIs(num, 1))
|
||||||
|
|
||||||
|
num, err = qs.Filter("user_name", "slene").Update(Params{
|
||||||
|
"Nums": ColValue(Col_Except, 5),
|
||||||
|
})
|
||||||
|
throwFail(t, err)
|
||||||
|
throwFail(t, AssertIs(num, 1))
|
||||||
|
|
||||||
|
user := User{UserName: "slene"}
|
||||||
|
err = dORM.Read(&user, "UserName")
|
||||||
|
throwFail(t, err)
|
||||||
|
throwFail(t, AssertIs(user.Nums, 30))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDelete(t *testing.T) {
|
func TestDelete(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user