From 34e62e9b4c8a93807cdb4fec37ab536ea535b3d7 Mon Sep 17 00:00:00 2001 From: tylerthail2019 Date: Mon, 18 Mar 2024 06:43:33 +0000 Subject: [PATCH] add IsZero check for custom struct column in the Update method (#2417) Co-authored-by: tyler Co-authored-by: Lunny Xiao Reviewed-on: https://gitea.com/xorm/xorm/pulls/2417 Reviewed-by: Lunny Xiao Co-authored-by: tylerthail2019 Co-committed-by: tylerthail2019 --- internal/statements/update.go | 3 ++ tests/types_test.go | 72 +++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/internal/statements/update.go b/internal/statements/update.go index 61342e33..34c6111a 100644 --- a/internal/statements/update.go +++ b/internal/statements/update.go @@ -126,6 +126,9 @@ func (statement *Statement) BuildUpdates(tableValue reflect.Value, if fieldValue.CanAddr() { if structConvert, ok := fieldValue.Addr().Interface().(convert.Conversion); ok { + if utils.IsZero(fieldValue.Interface()) { + continue + } data, err := structConvert.ToDB() if err != nil { return nil, nil, err diff --git a/tests/types_test.go b/tests/types_test.go index dfdb4766..bb07aeaf 100644 --- a/tests/types_test.go +++ b/tests/types_test.go @@ -619,3 +619,75 @@ func TestMyArray(t *testing.T) { assert.True(t, has) assert.EqualValues(t, v, m.Content) } + +type ZDecimal struct { + value *big.Int +} + +func (d *ZDecimal) FromDB(data []byte) error { + i, _ := strconv.ParseInt(string(data), 10, 64) + *d = ZDecimal{ + value: big.NewInt(i), + } + return nil +} + +func (d ZDecimal) ToDB() ([]byte, error) { + return []byte(fmt.Sprintf("%d", (d.value).Int64())), nil +} + +func (d ZDecimal) IsZero() bool { + if d.value == nil { + return true + } + return d.value.Sign() == 0 +} + +func (d ZDecimal) String() string { + if d.value == nil { + return "0" + } + return d.value.String() +} + +func TestZDecimal(t *testing.T) { + type ZMyMoney struct { + Id int64 + Account string + Amount ZDecimal + } + + assert.NoError(t, PrepareEngine()) + assertSync(t, new(ZMyMoney)) + + _, err := testEngine.Insert(&ZMyMoney{ + Account: "test", + Amount: ZDecimal{ + value: big.NewInt(10000000000000000), + }, + }) + assert.NoError(t, err) + + m := ZMyMoney{ + Id: 1, + } + has, err := testEngine.Get(&m) + assert.NoError(t, err) + assert.True(t, has) + + _, err = testEngine.Update(&ZMyMoney{ + Id: 1, + Account: "test2", + }) + assert.NoError(t, err) + m2 := ZMyMoney{ + Id: 1, + } + has, err = testEngine.Get(&m2) + + assert.NoError(t, err) + assert.True(t, has) + assert.Equal(t, "test2", "test2") + assert.False(t, m.Amount.IsZero()) + assert.Equal(t, "10000000000000000", m.Amount.String()) +}