From 36c79f5838a2d9b55df3ebe3182051871a0b61cd Mon Sep 17 00:00:00 2001 From: Eric Solender Date: Fri, 9 Oct 2020 15:00:49 -0400 Subject: [PATCH 1/2] start td fix --- integration_test.go | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/integration_test.go b/integration_test.go index 6b6f2e8..a070c74 100644 --- a/integration_test.go +++ b/integration_test.go @@ -68,6 +68,12 @@ func TestRawQuery(t *testing.T) { req.NotEmpty(raw) } +type tdArr []string +type tdArrOfTd []tdString +type tdMap map[string]interface{} +type tdMapTdSlice map[string]tdArr +type tdMapTdSliceOfTd map[string]tdArrOfTd + type propTest struct { BaseNode @@ -78,6 +84,12 @@ type propTest struct { MapSliceTdPrim map[string][]tdString `gogm:"name=prop5;properties"` SlicePrim []string `gogm:"name=prop6;properties"` SliceTdPrim []tdString `gogm:"name=prop7;properties"` + + TypeDefArr tdArr `gogm:"name=prop8;properties"` + TypeDefArrOfTD tdArrOfTd `gogm:"name=prop9;properties"` + TdMap tdMap `gogm:"name=prop10;properties"` + TdMapOfTdSlice tdMapTdSlice `gogm:"name=prop11;properties"` + TdMapTdSliceOfTd tdMapTdSliceOfTd `gogm:"name=prop12;properties"` } func TestIntegration(t *testing.T) { @@ -228,8 +240,19 @@ func testSave(sess *Session, req *require.Assertions) { MapSliceTdPrim: map[string][]tdString{ "test": {"test1", "test2"}, }, - SlicePrim: []string{"test2"}, - SliceTdPrim: []tdString{"test3"}, + SlicePrim: []string{"test2"}, + SliceTdPrim: []tdString{"test3"}, + TypeDefArr: []string{"test1"}, + TypeDefArrOfTD: []tdString{"test1"}, + TdMap: map[string]interface{}{ + "test": "test", + }, + TdMapOfTdSlice: map[string]tdArr{ + "test": []string{"test1", "test2"}, + }, + TdMapTdSliceOfTd: map[string]tdArrOfTd{ + "test": []tdString{"test1", "test2"}, + }, } req.Nil(sess.SaveDepth(&prop1, 0)) @@ -244,4 +267,9 @@ func testSave(sess *Session, req *require.Assertions) { req.EqualValues(prop1.MapSliceTdPrim, prop2.MapSliceTdPrim) req.EqualValues(prop1.SlicePrim, prop2.SlicePrim) req.EqualValues(prop1.SliceTdPrim, prop2.SliceTdPrim) + req.EqualValues(prop1.TypeDefArr, prop2.TypeDefArr) + req.EqualValues(prop1.TypeDefArrOfTD, prop2.TypeDefArrOfTD) + req.EqualValues(prop1.TdMap, prop2.TdMap) + req.EqualValues(prop1.TdMapOfTdSlice, prop2.TdMapOfTdSlice) + req.EqualValues(prop1.TdMapTdSliceOfTd, prop2.TdMapTdSliceOfTd) } From 6392d4d8b225a76b376fa9b8a32632a89f05b9e5 Mon Sep 17 00:00:00 2001 From: Eric Solender Date: Mon, 12 Oct 2020 13:28:18 -0400 Subject: [PATCH 2/2] fixed property typedef issue --- config.go | 2 +- decoder.go | 21 +++++++++++++-------- decoder_test.go | 30 ++++++++++++++++++++++++++++-- decorator.go | 21 ++++++++++++++++++--- decorator_test.go | 7 ++++--- integration_test.go | 7 ++++--- util.go | 2 +- util_test.go | 2 ++ 8 files changed, 71 insertions(+), 21 deletions(-) diff --git a/config.go b/config.go index fcffa69..701f732 100644 --- a/config.go +++ b/config.go @@ -154,7 +154,7 @@ func setupInit(isTest bool, conf *Config, mapTypes ...interface{}) error { return err } - log.Infof("mapped type %s", name) + log.Debugf("mapped type %s", name) mappedTypes.Set(name, *dc) } diff --git a/decoder.go b/decoder.go index e705de6..50183b3 100644 --- a/decoder.go +++ b/decoder.go @@ -553,10 +553,7 @@ func convertToValue(graphId int64, conf structDecoratorConfig, props map[string] continue } - var raw interface{} - var ok bool - - raw, ok = props[fieldConfig.Name] + raw, ok := props[fieldConfig.Name] if !ok { if fieldConfig.IsTypeDef { log.Debugf("skipping field %s since it is typedeffed and not defined", fieldConfig.Name) @@ -571,15 +568,14 @@ func convertToValue(graphId int64, conf structDecoratorConfig, props map[string] if fieldConfig.PropConfig.IsMap { var sub reflect.Type if fieldConfig.PropConfig.IsMapSlice { - sub = reflect.SliceOf(fieldConfig.PropConfig.SubType) + sub = fieldConfig.PropConfig.MapSliceType } else { sub = fieldConfig.PropConfig.SubType } mapType := reflect.MapOf(reflect.TypeOf(""), sub) mapVal := reflect.MakeMap(mapType) for k, v := range props { - if !strings.Contains(k, fieldConfig.Name) { - //not one of our map fields + if !strings.HasPrefix(k, fmt.Sprintf("%s.", fieldConfig.Name)) { continue } @@ -598,7 +594,7 @@ func convertToValue(graphId int64, conf structDecoratorConfig, props map[string] continue } rawLen := sliceVal.Len() - sl := reflect.MakeSlice(reflect.SliceOf(fieldConfig.PropConfig.SubType), rawLen, sliceVal.Cap()) + sl := reflect.MakeSlice(fieldConfig.PropConfig.MapSliceType, rawLen, sliceVal.Cap()) for i := 0; i < rawLen; i++ { slVal := sliceVal.Index(i) @@ -608,6 +604,9 @@ func convertToValue(graphId int64, conf structDecoratorConfig, props map[string] sl.Index(i).Set(slVal.Elem().Convert(fieldConfig.PropConfig.SubType)) } } + if fieldConfig.PropConfig.IsMapSliceTd { + sl = sl.Convert(fieldConfig.PropConfig.MapSliceType) + } mapVal.SetMapIndex(reflect.ValueOf(mapKey), sl) } else { vVal := reflect.ValueOf(v) @@ -618,6 +617,9 @@ func convertToValue(graphId int64, conf structDecoratorConfig, props map[string] } } } + if mapVal.Type() != fieldConfig.Type { + mapVal = mapVal.Convert(fieldConfig.Type) + } indirect.FieldByName(field).Set(mapVal) } else { if raw == nil || rawVal.IsZero() { @@ -635,6 +637,9 @@ func convertToValue(graphId int64, conf structDecoratorConfig, props map[string] sl.Index(i).Set(slVal.Elem().Convert(fieldConfig.PropConfig.SubType)) } } + if sl.Type() != fieldConfig.Type { + sl = sl.Convert(fieldConfig.Type) + } indirect.FieldByName(field).Set(sl) } } else { diff --git a/decoder_test.go b/decoder_test.go index 42fe798..bc95a8c 100644 --- a/decoder_test.go +++ b/decoder_test.go @@ -213,6 +213,11 @@ type propsTest struct { PropTest1 map[string]string `gogm:"properties;name=props1"` PropsTest2 []string `gogm:"properties;name=props2"` PropsTest3 []int `gogm:"properties;name=props3"` + PropsTest4 tdArr `gogm:"name=props4;properties"` + PropsTest5 tdArrOfTd `gogm:"name=props5;properties"` + PropsTest6 tdMap `gogm:"name=props6;properties"` + PropsTest7 tdMapTdSlice `gogm:"name=props7;properties"` + PropsTest8 tdMapTdSliceOfTd `gogm:"name=props8;properties"` } func TestDecode(t *testing.T) { @@ -658,8 +663,13 @@ func TestInnerDecode(t *testing.T) { "props0.test.test": "test", "props0.test2": 1, "props1.test": "test", - "props2": []string{"test"}, - "props3": []int{1, 2}, + "props2": []interface{}{"test"}, + "props3": []interface{}{1, 2}, + "props4": []interface{}{"test1", "test2"}, + "props5": []interface{}{"tdtest"}, + "props6.test": 1, + "props7.test": []interface{}{"test1", "test2"}, + "props8.test3": []interface{}{"test1", "test"}, }, }, }, @@ -681,6 +691,17 @@ func TestInnerDecode(t *testing.T) { }, PropsTest2: []string{"test"}, PropsTest3: []int{1, 2}, + PropsTest4: []string{"test1", "test2"}, + PropsTest5: []tdString{"tdtest"}, + PropsTest6: map[string]interface{}{ + "test": 1, + }, + PropsTest7: map[string]tdArr{ + "test": []string{"test1", "test2"}, + }, + PropsTest8: map[string]tdArrOfTd{ + "test3": []tdString{"test1", "test"}, + }, } req.Nil(innerDecode(vars5, &readin5)) @@ -691,6 +712,11 @@ func TestInnerDecode(t *testing.T) { req.EqualValues(r.PropTest1["test"], readin5.PropTest1["test"]) req.EqualValues(r.PropsTest2, readin5.PropsTest2) req.EqualValues(r.PropsTest3, readin5.PropsTest3) + req.EqualValues(r.PropsTest4, readin5.PropsTest4) + req.EqualValues(r.PropsTest5, readin5.PropsTest5) + req.EqualValues(r.PropsTest6, readin5.PropsTest6) + req.EqualValues(r.PropsTest7, readin5.PropsTest7) + req.EqualValues(r.PropsTest8, readin5.PropsTest8) //multi single vars6 := [][]interface{}{ diff --git a/decorator.go b/decorator.go index 52021a4..0f24c57 100644 --- a/decorator.go +++ b/decorator.go @@ -75,9 +75,11 @@ const ( type propConfig struct { // IsMap if false assume slice - IsMap bool - IsMapSlice bool - SubType reflect.Type + IsMap bool + IsMapSlice bool + IsMapSliceTd bool + MapSliceType reflect.Type + SubType reflect.Type } //decorator config defines configuration of GoGM field @@ -388,6 +390,19 @@ func newDecoratorConfig(decorator, name string, varType reflect.Type) (*decorato sub := varType.Elem() if sub.Kind() == reflect.Slice { conf.IsMapSlice = true + // check if actual slice is type deffed + isAliased, aliasType, err := getActualTypeIfAliased(sub) + if err != nil { + return nil, err + } + if !isAliased { + conf.MapSliceType = sub + } else if aliasType != nil && isAliased { + conf.MapSliceType = aliasType + conf.IsMapSliceTd = true + } else { + return nil, fmt.Errorf("type found to be aliased but alias type nil") + } conf.SubType = sub.Elem() } else { conf.SubType = sub diff --git a/decorator_test.go b/decorator_test.go index 9fdb8a1..54e570c 100644 --- a/decorator_test.go +++ b/decorator_test.go @@ -546,9 +546,10 @@ func TestGetStructDecoratorConfig(t *testing.T) { Name: "props3", Type: reflect.TypeOf(map[string][]int{}), PropConfig: &propConfig{ - IsMap: true, - IsMapSlice: true, - SubType: reflect.TypeOf(int(0)), + IsMap: true, + IsMapSlice: true, + SubType: reflect.TypeOf(int(0)), + MapSliceType: reflect.TypeOf([]int{}), }, }, "PropsSliceInterface": { diff --git a/integration_test.go b/integration_test.go index a070c74..0ac66b2 100644 --- a/integration_test.go +++ b/integration_test.go @@ -95,6 +95,7 @@ type propTest struct { func TestIntegration(t *testing.T) { if testing.Short() { t.Skip() + return } req := require.New(t) @@ -240,9 +241,9 @@ func testSave(sess *Session, req *require.Assertions) { MapSliceTdPrim: map[string][]tdString{ "test": {"test1", "test2"}, }, - SlicePrim: []string{"test2"}, - SliceTdPrim: []tdString{"test3"}, - TypeDefArr: []string{"test1"}, + SlicePrim: []string{"test2"}, + SliceTdPrim: []tdString{"test3"}, + TypeDefArr: []string{"test1"}, TypeDefArrOfTD: []tdString{"test1"}, TdMap: map[string]interface{}{ "test": "test", diff --git a/util.go b/util.go index 29bd78b..f2b3a57 100644 --- a/util.go +++ b/util.go @@ -187,7 +187,7 @@ func (r *relationConfigs) Add(nodeType, relationship, fieldType string, dec deco r.configs[key][fieldType] = []decoratorConfig{} } - log.Infof("mapped relations [%s][%s][%v]", key, fieldType, len(r.configs[key][fieldType])) + log.Debugf("mapped relations [%s][%s][%v]", key, fieldType, len(r.configs[key][fieldType])) r.configs[key][fieldType] = append(r.configs[key][fieldType], dec) } diff --git a/util_test.go b/util_test.go index a9a2939..79fe0c9 100644 --- a/util_test.go +++ b/util_test.go @@ -134,6 +134,8 @@ func TestToCypherParamsMap(t *testing.T) { "props0.test": "testvalue", "props2": []string(nil), "props3": []int(nil), + "props4": tdArr(nil), + "props5": tdArrOfTd(nil), }, params) }