Fix bug of ToDB when update on a nil pointer (#1786)

Fix test

Fix bug

Fix bug

Add test for insert nil struct field

Fix test

Fix bug of ToDB when update on a nil pointer

Reviewed-on: https://gitea.com/xorm/xorm/pulls/1786
This commit is contained in:
Lunny Xiao 2020-09-08 15:40:26 +00:00
parent b422930617
commit 1b200bdcba
3 changed files with 67 additions and 14 deletions

View File

@ -188,6 +188,9 @@ func TestForUpdate(t *testing.T) {
// lock is NOT used // lock is NOT used
wg.Add(1) wg.Add(1)
wg2 := &sync.WaitGroup{}
wg2.Add(1)
go func() { go func() {
f3 := new(ForUpdate) f3 := new(ForUpdate)
session3.Where("id = ?", 1) session3.Where("id = ?", 1)
@ -201,10 +204,10 @@ func TestForUpdate(t *testing.T) {
t.Errorf("read lock failed") t.Errorf("read lock failed")
} }
wg.Done() wg.Done()
wg2.Done()
}() }()
// wait for go rountines wg2.Wait()
time.Sleep(50 * time.Millisecond)
f := new(ForUpdate) f := new(ForUpdate)
f.Name = "updated by session1" f.Name = "updated by session1"
@ -1350,3 +1353,50 @@ func TestUpdateMultiplePK(t *testing.T) {
_, err = testEngine.ID(&MySlice{test.Id, test.Name}).Update(test) _, err = testEngine.ID(&MySlice{test.Id, test.Name}).Update(test)
assert.NoError(t, err) assert.NoError(t, err)
} }
type TestFieldType1 struct {
cb []byte
}
func (a *TestFieldType1) FromDB(src []byte) error {
a.cb = src
return nil
}
func (a TestFieldType1) ToDB() ([]byte, error) {
return a.cb, nil
}
type TestTable1 struct {
Id int64
Field1 *TestFieldType1 `xorm:"text"`
UpdateTime time.Time
}
func TestNilFromDB(t *testing.T) {
assert.NoError(t, PrepareEngine())
assertSync(t, new(TestTable1))
cnt, err := testEngine.Insert(&TestTable1{
Field1: &TestFieldType1{
cb: []byte("string"),
},
UpdateTime: time.Now(),
})
assert.NoError(t, err)
assert.EqualValues(t, 1, cnt)
cnt, err = testEngine.Update(TestTable1{
UpdateTime: time.Now().Add(time.Second),
}, TestTable1{
Id: 1,
})
assert.NoError(t, err)
assert.EqualValues(t, 1, cnt)
cnt, err = testEngine.Insert(&TestTable1{
UpdateTime: time.Now(),
})
assert.NoError(t, err)
assert.EqualValues(t, 1, cnt)
}

View File

@ -130,7 +130,7 @@ func (statement *Statement) BuildUpdates(tableValue reflect.Value,
} }
} }
if structConvert, ok := fieldValue.Interface().(convert.Conversion); ok { if structConvert, ok := fieldValue.Interface().(convert.Conversion); ok && !fieldValue.IsNil() {
data, err := structConvert.ToDB() data, err := structConvert.ToDB()
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err

View File

@ -36,18 +36,21 @@ func (statement *Statement) Value2Interface(col *schemas.Column, fieldValue refl
} }
} }
if fieldConvert, ok := fieldValue.Interface().(convert.Conversion); ok { isNil := fieldValue.Kind() == reflect.Ptr && fieldValue.IsNil()
data, err := fieldConvert.ToDB() if !isNil {
if err != nil { if fieldConvert, ok := fieldValue.Interface().(convert.Conversion); ok {
return nil, err data, err := fieldConvert.ToDB()
if err != nil {
return nil, err
}
if col.SQLType.IsBlob() {
return data, nil
}
if nil == data {
return nil, nil
}
return string(data), nil
} }
if col.SQLType.IsBlob() {
return data, nil
}
if nil == data {
return nil, nil
}
return string(data), nil
} }
fieldType := fieldValue.Type() fieldType := fieldValue.Type()