diff --git a/result_set_test.go b/result_set_test.go index aaccd155..4a559e75 100644 --- a/result_set_test.go +++ b/result_set_test.go @@ -835,6 +835,102 @@ func TestScan(t *testing.T) { assert.Equal(t, true, testStructList[1].Col3) } +func TestScanWithNestStruct(t *testing.T) { + resp := &graph.ExecutionResponse{ + ErrorCode: nebula.ErrorCode_SUCCEEDED, + LatencyInUs: 1000, + Data: getNestDateset(), + SpaceName: []byte("test_space"), + ErrorMsg: []byte("test"), + PlanDesc: graph.NewPlanDescription(), + Comment: []byte("test_comment")} + resultSet, err := genResultSet(resp, testTimezone) + if err != nil { + t.Error(err) + } + + type Person struct { + Name string `nebula:"name"` + City string `nebula:"city"` + } + type Friend struct { + CreatedAt string `nebula:"created_at"` + } + type Result struct { + Nodes []Person `nebula:"nodes"` + Edges []Friend `nebula:"relationships"` + } + + var results []Result + err = resultSet.Scan(&results) + if err != nil { + t.Error(err) + } + assert.Equal(t, 1, len(results)) + assert.Equal(t, "Tom", results[0].Nodes[0].Name) + assert.Equal(t, "Shanghai", results[0].Nodes[0].City) + assert.Equal(t, "Bob", results[0].Nodes[1].Name) + assert.Equal(t, "Hangzhou", results[0].Nodes[1].City) + assert.Equal(t, "2024-07-07", results[0].Edges[0].CreatedAt) + assert.Equal(t, "2024-07-07", results[0].Edges[1].CreatedAt) + + // Scan again should work + err = resultSet.Scan(&results) + if err != nil { + t.Error(err) + } + assert.Equal(t, 2, len(results)) +} + +func TestScanWithNestStructPtr(t *testing.T) { + resp := &graph.ExecutionResponse{ + ErrorCode: nebula.ErrorCode_SUCCEEDED, + LatencyInUs: 1000, + Data: getNestDateset(), + SpaceName: []byte("test_space"), + ErrorMsg: []byte("test"), + PlanDesc: graph.NewPlanDescription(), + Comment: []byte("test_comment")} + resultSet, err := genResultSet(resp, testTimezone) + if err != nil { + t.Error(err) + } + + type Person struct { + Name string `nebula:"name"` + City string `nebula:"city"` + } + type Friend struct { + CreatedAt string `nebula:"created_at"` + } + type Result struct { + Nodes []*Person `nebula:"nodes"` + Edges []*Friend `nebula:"relationships"` + } + + // TODO: actually, the `results` should be []*Result, + // we still need to support this case + var results []Result + err = resultSet.Scan(&results) + if err != nil { + t.Error(err) + } + assert.Equal(t, 1, len(results)) + assert.Equal(t, "Tom", results[0].Nodes[0].Name) + assert.Equal(t, "Shanghai", results[0].Nodes[0].City) + assert.Equal(t, "Bob", results[0].Nodes[1].Name) + assert.Equal(t, "Hangzhou", results[0].Nodes[1].City) + assert.Equal(t, "2024-07-07", results[0].Edges[0].CreatedAt) + assert.Equal(t, "2024-07-07", results[0].Edges[1].CreatedAt) + + // Scan again should work + err = resultSet.Scan(&results) + if err != nil { + t.Error(err) + } + assert.Equal(t, 2, len(results)) +} + func TestIntVid(t *testing.T) { vertex := getVertexInt(101, 3, 5) node, err := genNode(vertex, testTimezone) @@ -1032,6 +1128,83 @@ func getDateset2() *nebula.DataSet { } } +func getNestDateset() *nebula.DataSet { + colNames := [][]byte{ + []byte("nodes"), + []byte("relationships"), + } + var list1 = nebula.NewValue() + list1.SetLVal(&nebula.NList{ + Values: []*nebula.Value{ + { + VVal: &nebula.Vertex{ + Vid: &nebula.Value{SVal: []byte("person_id_0")}, + Tags: []*nebula.Tag{ + { + Name: []byte("person"), + Props: map[string]*nebula.Value{ + "name": {SVal: []byte("Tom")}, + "city": {SVal: []byte("Shanghai")}, + }, + }, + }, + }, + }, + { + VVal: &nebula.Vertex{ + Vid: &nebula.Value{SVal: []byte("person_id_1")}, + Tags: []*nebula.Tag{ + { + Name: []byte("person"), + Props: map[string]*nebula.Value{ + "name": {SVal: []byte("Bob")}, + "city": {SVal: []byte("Hangzhou")}, + }, + }, + }, + }, + }, + }, + }) + + var list2 = nebula.NewValue() + list2.SetLVal(&nebula.NList{ + Values: []*nebula.Value{ + { + EVal: &nebula.Edge{ + Src: &nebula.Value{SVal: []byte("person_id_0")}, + Dst: &nebula.Value{SVal: []byte("person_id_1")}, + Name: []byte("friend"), + Props: map[string]*nebula.Value{ + "created_at": {SVal: []byte("2024-07-07")}, + }, + }, + }, + { + EVal: &nebula.Edge{ + Src: &nebula.Value{SVal: []byte("person_id_1")}, + Dst: &nebula.Value{SVal: []byte("person_id_0")}, + Name: []byte("friend"), + Props: map[string]*nebula.Value{ + "created_at": {SVal: []byte("2024-07-07")}, + }, + }, + }, + }, + }) + + valueList := []*nebula.Value{list1, list2} + var rows []*nebula.Row + row := &nebula.Row{ + Values: valueList, + } + rows = append(rows, row) + return &nebula.DataSet{ + ColumnNames: colNames, + Rows: rows, + } +} + func setIVal(ival int) *nebula.Value { var value = nebula.NewValue() newNum := new(int64)