Skip to content

Commit 80dea08

Browse files
committed
cache: Fix ApplyModifications for pointer fields
Signed-off-by: Dave Tucker <[email protected]>
1 parent ceaf12d commit 80dea08

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

cache/cache.go

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,7 @@ func (t *TableCache) CreateModel(tableName string, row *ovsdb.Row, uuid string)
780780
}
781781

782782
// ApplyModifications applies the contents of a RowUpdate2.Modify to a model
783+
// nolint: gocyclo
783784
func (t *TableCache) ApplyModifications(tableName string, base model.Model, update ovsdb.Row) error {
784785
table := t.mapper.Schema.Table(tableName)
785786
if table == nil {
@@ -797,19 +798,24 @@ func (t *TableCache) ApplyModifications(tableName string, base model.Model, upda
797798
if k == "_uuid" {
798799
continue
799800
}
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+
}
801809
if err != nil {
802810
return err
803811
}
804812
nv := reflect.ValueOf(value)
805813

806-
switch nv.Kind() {
814+
switch reflect.ValueOf(base).Kind() {
807815
case reflect.Slice, reflect.Array:
808816
// The difference between two sets are all elements that only belong to one of the sets.
809-
810817
// Iterate new values
811818
for i := 0; i < nv.Len(); i++ {
812-
813819
// search for match in base values
814820
baseValue, err := info.FieldByColumn(k)
815821
if err != nil {
@@ -837,7 +843,25 @@ func (t *TableCache) ApplyModifications(tableName string, base model.Model, upda
837843
}
838844
}
839845
}
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+
}
841865
case reflect.Map:
842866
// The difference between two maps are all key-value pairs whose keys appears in only one of the maps,
843867
// plus the key-value pairs whose keys appear in both maps but with different values.

ovsdb/updates2.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ func (r *RowUpdate2) Merge(new *RowUpdate2) {
8181
oMap.GoMap[newK] = newV
8282
}
8383
}
84-
default:
85-
panic("ARGH!")
8684
}
8785
}
8886
}

0 commit comments

Comments
 (0)