@@ -780,6 +780,7 @@ func (t *TableCache) CreateModel(tableName string, row *ovsdb.Row, uuid string)
780
780
}
781
781
782
782
// ApplyModifications applies the contents of a RowUpdate2.Modify to a model
783
+ // nolint: gocyclo
783
784
func (t * TableCache ) ApplyModifications (tableName string , base model.Model , update ovsdb.Row ) error {
784
785
table := t .mapper .Schema .Table (tableName )
785
786
if table == nil {
@@ -797,19 +798,24 @@ func (t *TableCache) ApplyModifications(tableName string, base model.Model, upda
797
798
if k == "_uuid" {
798
799
continue
799
800
}
800
- value , err := ovsdb .OvsToNative (schema .Column (k ), v )
801
+
802
+ var value interface {}
803
+ value , err = ovsdb .OvsToNative (schema .Column (k ), v )
804
+ // we can overflow the max of a set with min: 0, max: 1 here because of the update2/update3 notation
805
+ // which to replace "foo" with "bar" would send a set with ["foo", "bar"]
806
+ if err != nil && schema .Column (k ).Type == ovsdb .TypeSet && schema .Column (k ).TypeObj .Max () == 1 {
807
+ value , err = ovsdb .OvsToNativeSlice (schema .Column (k ).TypeObj .Key .Type , v )
808
+ }
801
809
if err != nil {
802
810
return err
803
811
}
804
812
nv := reflect .ValueOf (value )
805
813
806
- switch nv .Kind () {
814
+ switch reflect . ValueOf ( base ) .Kind () {
807
815
case reflect .Slice , reflect .Array :
808
816
// The difference between two sets are all elements that only belong to one of the sets.
809
-
810
817
// Iterate new values
811
818
for i := 0 ; i < nv .Len (); i ++ {
812
-
813
819
// search for match in base values
814
820
baseValue , err := info .FieldByColumn (k )
815
821
if err != nil {
@@ -837,7 +843,25 @@ func (t *TableCache) ApplyModifications(tableName string, base model.Model, upda
837
843
}
838
844
}
839
845
}
840
-
846
+ case reflect .Ptr :
847
+ // With a pointer type, the update value is a set with 2 elements [old, new]
848
+ if nv .Len () != 2 {
849
+ panic ("expected a slice with 2 elements" )
850
+ }
851
+ // the new value is the value in the slice which isn't equal to the existing string
852
+ for i := 0 ; i < nv .Len (); i ++ {
853
+ baseValue , err := info .FieldByColumn (k )
854
+ if err != nil {
855
+ return err
856
+ }
857
+ bv := reflect .ValueOf (baseValue )
858
+ if nv .Index (i ) != bv {
859
+ err = info .SetField (k , nv .Index (i ).Addr ().Interface ())
860
+ if err != nil {
861
+ return err
862
+ }
863
+ }
864
+ }
841
865
case reflect .Map :
842
866
// The difference between two maps are all key-value pairs whose keys appears in only one of the maps,
843
867
// plus the key-value pairs whose keys appear in both maps but with different values.
0 commit comments