Fix bug when ID used but no reference table given #1709

Merged
lunny merged 1 commits from lunny/fix_update into master 2020-06-13 01:20:28 +00:00
2 changed files with 31 additions and 2 deletions

View File

@ -12,6 +12,7 @@ import (
"github.com/stretchr/testify/assert"
"xorm.io/xorm"
"xorm.io/xorm/internal/statements"
"xorm.io/xorm/internal/utils"
"xorm.io/xorm/names"
)
@ -39,6 +40,14 @@ func TestUpdateMap(t *testing.T) {
})
assert.NoError(t, err)
assert.EqualValues(t, 1, cnt)
cnt, err = testEngine.Table("update_table").ID(tb.Id).Update(map[string]interface{}{
"name": "test2",
"age": 36,
})
assert.Error(t, err)
assert.True(t, statements.IsIDConditionWithNoTableErr(err))
assert.EqualValues(t, 0, cnt)
}
func TestUpdateLimit(t *testing.T) {
@ -988,7 +997,7 @@ func TestUpdateMapContent(t *testing.T) {
assert.EqualValues(t, false, c2.IsMan)
assert.EqualValues(t, 2, c2.Gender)
cnt, err = testEngine.Table(testEngine.TableName(new(UpdateMapContent))).ID(c.Id).Update(map[string]interface{}{
cnt, err = testEngine.Table(new(UpdateMapContent)).ID(c.Id).Update(map[string]interface{}{
"age": 15,
"is_man": true,
"gender": 1,

View File

@ -20,6 +20,21 @@ var (
uintType = reflect.TypeOf(uint64(0))
)
// ErrIDConditionWithNoTable represents an error there is no reference table with an ID condition
type ErrIDConditionWithNoTable struct {
ID schemas.PK
}
func (err ErrIDConditionWithNoTable) Error() string {
return fmt.Sprintf("ID condition %#v need reference table", err.ID)
}
// IsIDConditionWithNoTableErr return true if the err is ErrIDConditionWithNoTable
func IsIDConditionWithNoTableErr(err error) bool {
_, ok := err.(ErrIDConditionWithNoTable)
return ok
}
// ID generate "where id = ? " statement or for composite key "where key1 = ? and key2 = ?"
func (statement *Statement) ID(id interface{}) *Statement {
switch t := id.(type) {
@ -58,11 +73,16 @@ func (statement *Statement) ID(id interface{}) *Statement {
return statement
}
// ProcessIDParam handles the process of id condition
func (statement *Statement) ProcessIDParam() error {
if statement.idParam == nil || statement.RefTable == nil {
if statement.idParam == nil {
return nil
}
if statement.RefTable == nil {
return ErrIDConditionWithNoTable{statement.idParam}
}
if len(statement.RefTable.PrimaryKeys) != len(statement.idParam) {
return fmt.Errorf("ID condition is error, expect %d primarykeys, there are %d",
len(statement.RefTable.PrimaryKeys),