Skip to content

Commit a2f22e2

Browse files
author
Qiu Jian
committed
fix: update ignoring trivial changes
1 parent 3b18bc6 commit a2f22e2

3 files changed

Lines changed: 238 additions & 0 deletions

File tree

reflect.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"time"
2424

2525
"yunion.io/x/jsonutils"
26+
"yunion.io/x/log"
2627
"yunion.io/x/pkg/errors"
2728
"yunion.io/x/pkg/gotypes"
2829
"yunion.io/x/pkg/tristate"
@@ -758,3 +759,117 @@ func ConvertValueToString(val interface{}) string {
758759
}
759760
return jsonutils.Marshal(val).String()
760761
}
762+
763+
func getFloatValue(val interface{}) (float64, error) {
764+
switch v := val.(type) {
765+
case float32:
766+
return float64(v), nil
767+
case float64:
768+
return v, nil
769+
case int:
770+
return float64(v), nil
771+
case int8:
772+
return float64(v), nil
773+
case int16:
774+
return float64(v), nil
775+
case int32:
776+
return float64(v), nil
777+
case int64:
778+
return float64(v), nil
779+
case uint:
780+
return float64(v), nil
781+
case uint8:
782+
return float64(v), nil
783+
case uint16:
784+
return float64(v), nil
785+
case uint32:
786+
return float64(v), nil
787+
case uint64:
788+
return float64(v), nil
789+
case *float32:
790+
return float64(*v), nil
791+
case *float64:
792+
return *v, nil
793+
case *int:
794+
return float64(*v), nil
795+
case *int8:
796+
return float64(*v), nil
797+
case *int16:
798+
return float64(*v), nil
799+
case *int32:
800+
return float64(*v), nil
801+
case *int64:
802+
return float64(*v), nil
803+
case *uint:
804+
return float64(*v), nil
805+
case *uint8:
806+
return float64(*v), nil
807+
case *uint16:
808+
return float64(*v), nil
809+
case *uint32:
810+
return float64(*v), nil
811+
case *uint64:
812+
return float64(*v), nil
813+
case string:
814+
return strconv.ParseFloat(v, 64)
815+
case *string:
816+
return strconv.ParseFloat(*v, 64)
817+
}
818+
return 0, errors.ErrInvalidFormat
819+
}
820+
821+
func getTimeValue(val interface{}) (time.Time, error) {
822+
switch v := val.(type) {
823+
case time.Time:
824+
return v, nil
825+
case *time.Time:
826+
return *v, nil
827+
case string:
828+
return timeutils.ParseTimeStr(v)
829+
case *string:
830+
return timeutils.ParseTimeStr(*v)
831+
}
832+
return time.Time{}, errors.ErrInvalidFormat
833+
}
834+
835+
const MIN_FLOAT_EQUAL_DIFF = float64(0.000001)
836+
837+
func floatEqual(of, nf float64) bool {
838+
if of > nf {
839+
return of < MIN_FLOAT_EQUAL_DIFF+nf
840+
} else if of < nf {
841+
return of+MIN_FLOAT_EQUAL_DIFF > nf
842+
} else {
843+
return true
844+
}
845+
}
846+
847+
const MIN_MICRO_SECOND_EQUAL_DIFF = 1000000
848+
849+
func timeEqual(of, nf time.Time) bool {
850+
log.Debugf("timeEqual: %s - %s", of, nf)
851+
ofUnix := of.UnixMicro()
852+
nfUnix := nf.UnixMicro()
853+
if ofUnix == nfUnix {
854+
return true
855+
}
856+
if ofUnix > nfUnix {
857+
return ofUnix < MIN_MICRO_SECOND_EQUAL_DIFF+nfUnix
858+
} else {
859+
return ofUnix+MIN_MICRO_SECOND_EQUAL_DIFF > nfUnix
860+
}
861+
}
862+
863+
func EqualsGrossValue(of, nf interface{}) bool {
864+
ofFloat, ofErr := getFloatValue(of)
865+
nfFloat, nfErr := getFloatValue(nf)
866+
if ofErr == nil && nfErr == nil {
867+
return floatEqual(ofFloat, nfFloat)
868+
}
869+
ofTime, ofErr := getTimeValue(of)
870+
nfTime, nfErr := getTimeValue(nf)
871+
if ofErr == nil && nfErr == nil {
872+
return timeEqual(ofTime, nfTime)
873+
}
874+
return false
875+
}

reflect_test.go

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,3 +401,123 @@ func TestConvertValueToTriState(t *testing.T) {
401401
}
402402
}
403403
}
404+
405+
func TestEqualsGrossValue(t *testing.T) {
406+
cases := []struct {
407+
of interface{}
408+
nf interface{}
409+
want bool
410+
}{
411+
{
412+
of: 1.0,
413+
nf: 1.0,
414+
want: true,
415+
},
416+
{
417+
of: 1.0,
418+
nf: 1.00001,
419+
want: false,
420+
},
421+
{
422+
of: 1.0,
423+
nf: 0.99999,
424+
want: false,
425+
},
426+
{
427+
of: 1.0,
428+
nf: 1.000002,
429+
want: false,
430+
},
431+
{
432+
of: 1.0,
433+
nf: 0.999998,
434+
want: false,
435+
},
436+
{
437+
of: 1.0,
438+
nf: 1.000001,
439+
want: false,
440+
},
441+
{
442+
of: 1.0,
443+
nf: 1.0000011,
444+
want: false,
445+
},
446+
{
447+
of: 1.0,
448+
nf: 1.0000009,
449+
want: true,
450+
},
451+
{
452+
of: 1.0,
453+
nf: 0.999999,
454+
want: false,
455+
},
456+
{
457+
of: 1.0,
458+
nf: 0.9999989,
459+
want: false,
460+
},
461+
{
462+
of: 1.0,
463+
nf: 0.9999991,
464+
want: true,
465+
},
466+
{
467+
of: 1.0,
468+
nf: 1.0000001,
469+
want: true,
470+
},
471+
{
472+
of: 1.0,
473+
nf: 0.9999999,
474+
want: true,
475+
},
476+
{
477+
of: "1.0",
478+
nf: "0.9999999",
479+
want: true,
480+
},
481+
{
482+
of: 1,
483+
nf: "0.9999999",
484+
want: true,
485+
},
486+
{
487+
of: "2025-01-01T00:00:00.000000Z",
488+
nf: "2025-01-01T00:00:00.000001Z",
489+
want: true,
490+
},
491+
{
492+
of: "2025-01-01T00:00:00.000000Z",
493+
nf: "2025-01-01T00:00:00.001001Z",
494+
want: true,
495+
},
496+
{
497+
of: "2025-01-01T00:00:00.000000Z",
498+
nf: "2025-01-01T00:00:01.001000Z",
499+
want: false,
500+
},
501+
{
502+
of: "2025-01-01T00:00:00.999999Z",
503+
nf: "2025-01-01T00:00:01.000000Z",
504+
want: true,
505+
},
506+
{
507+
of: "2025-01-01T00:00:00.999999Z",
508+
nf: "2025-01-01T00:00:01.999000Z",
509+
want: true,
510+
},
511+
{
512+
of: "2025-01-01T00:00:00.999999Z",
513+
nf: "2025-01-01T00:00:01.999999Z",
514+
want: false,
515+
},
516+
}
517+
for _, c := range cases {
518+
got := EqualsGrossValue(c.of, c.nf)
519+
if got != c.want {
520+
t.Errorf("want %v got %v for %v and %v", c.want, got, c.of, c.nf)
521+
}
522+
}
523+
}

update.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ func (us *SUpdateSession) SaveUpdateSql(dt interface{}) (*SUpdateSQLResult, erro
174174
if ofJsonStr == nfJsonStr {
175175
continue
176176
}
177+
if EqualsGrossValue(of, nf) {
178+
continue
179+
}
177180
}
178181
if c.IsZero(nf) && c.IsText() {
179182
nf = nil

0 commit comments

Comments
 (0)