From c371af5886aab8d048837d3759236ecce452ac72 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 12 Jun 2020 21:56:36 +0800 Subject: [PATCH] Fix bug when ID used but no reference table given --- integrations/session_update_test.go | 11 ++++++++++- internal/statements/pk.go | 22 +++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/integrations/session_update_test.go b/integrations/session_update_test.go index 8800246c..1bc1f32a 100644 --- a/integrations/session_update_test.go +++ b/integrations/session_update_test.go @@ -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, diff --git a/internal/statements/pk.go b/internal/statements/pk.go index d0787719..59da89c0 100644 --- a/internal/statements/pk.go +++ b/internal/statements/pk.go @@ -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), -- 2.40.1