Skip to content

Commit 2538e5e

Browse files
committed
Support scan Nebula vertex and edge
1 parent d12bd94 commit 2538e5e

File tree

1 file changed

+108
-25
lines changed

1 file changed

+108
-25
lines changed

result_set.go

+108-25
Original file line numberDiff line numberDiff line change
@@ -335,13 +335,13 @@ func (res ResultSet) Scan(v interface{}) error {
335335
}
336336

337337
// Scan scans the rows into the given value.
338-
func (res ResultSet) scanRow(row *nebula.Row, colNames []string, t reflect.Type) (reflect.Value, error) {
338+
func (res ResultSet) scanRow(row *nebula.Row, colNames []string, rowType reflect.Type) (reflect.Value, error) {
339339
rowVals := row.GetValues()
340340

341-
val := reflect.New(t).Elem()
341+
val := reflect.New(rowType).Elem()
342342

343-
for fIdx := 0; fIdx < t.NumField(); fIdx++ {
344-
f := t.Field(fIdx)
343+
for fIdx := 0; fIdx < rowType.NumField(); fIdx++ {
344+
f := rowType.Field(fIdx)
345345
tag := f.Tag.Get("nebula")
346346

347347
if tag == "" {
@@ -356,33 +356,116 @@ func (res ResultSet) scanRow(row *nebula.Row, colNames []string, t reflect.Type)
356356

357357
rowVal := rowVals[cIdx]
358358

359-
switch f.Type.Kind() {
360-
case reflect.Bool:
361-
val.Field(fIdx).SetBool(rowVal.GetBVal())
362-
case reflect.Int:
363-
val.Field(fIdx).SetInt(rowVal.GetIVal())
364-
case reflect.Int8:
365-
val.Field(fIdx).SetInt(rowVal.GetIVal())
366-
case reflect.Int16:
367-
val.Field(fIdx).SetInt(rowVal.GetIVal())
368-
case reflect.Int32:
369-
val.Field(fIdx).SetInt(rowVal.GetIVal())
370-
case reflect.Int64:
371-
val.Field(fIdx).SetInt(rowVal.GetIVal())
372-
case reflect.Float32:
373-
val.Field(fIdx).SetFloat(rowVal.GetFVal())
374-
case reflect.Float64:
375-
val.Field(fIdx).SetFloat(rowVal.GetFVal())
376-
case reflect.String:
377-
val.Field(fIdx).SetString(string(rowVal.GetSVal()))
378-
default:
379-
return val, errors.New("scan: not support type")
359+
if f.Type.Kind() == reflect.Slice {
360+
list := rowVal.GetLVal()
361+
err := scanListCol(list.Values, val.Field(fIdx), f.Type)
362+
if err != nil {
363+
return val, err
364+
}
365+
} else {
366+
err := scanPrimitiveCol(rowVal, val.Field(fIdx), f.Type.Kind())
367+
if err != nil {
368+
return val, err
369+
}
380370
}
381371
}
382372

383373
return val, nil
384374
}
385375

376+
func scanListCol(vals []*nebula.Value, listVal reflect.Value, sliceType reflect.Type) error {
377+
var listCol = reflect.MakeSlice(sliceType, len(vals), len(vals))
378+
for _, val := range vals {
379+
switch sliceType.Elem().Kind() {
380+
case reflect.Struct:
381+
ele := reflect.New(sliceType.Elem()).Elem()
382+
err := scanStructField(val, ele, sliceType.Elem())
383+
if err != nil {
384+
return err
385+
}
386+
listCol = reflect.Append(listCol, ele)
387+
default:
388+
return errors.New("scan: not support list type")
389+
}
390+
}
391+
392+
listVal.Set(listCol)
393+
394+
return nil
395+
}
396+
397+
func scanStructField(val *nebula.Value, eleVal reflect.Value, eleType reflect.Type) error {
398+
vertex := val.GetVVal()
399+
if vertex != nil {
400+
tags := vertex.GetTags()
401+
if len(tags) != 0 {
402+
tag := tags[0] // TODO: support multiple tags
403+
props := tag.GetProps()
404+
err := scanValFromProps(props, eleVal, eleType)
405+
if err != nil {
406+
return err
407+
}
408+
}
409+
return nil
410+
}
411+
412+
edge := val.GetEVal()
413+
if edge != nil {
414+
props := edge.GetProps()
415+
err := scanValFromProps(props, eleVal, eleType)
416+
if err != nil {
417+
return err
418+
}
419+
return nil
420+
}
421+
422+
return errors.New("scan: not support struct type")
423+
}
424+
425+
func scanValFromProps(props map[string]*nebula.Value, val reflect.Value, tpe reflect.Type) error {
426+
for fIdx := 0; fIdx < tpe.NumField(); fIdx++ {
427+
f := tpe.Field(fIdx)
428+
n := f.Tag.Get("nebula")
429+
v, ok := props[n]
430+
if !ok {
431+
continue
432+
}
433+
err := scanPrimitiveCol(v, val.Field(fIdx), f.Type.Kind())
434+
if err != nil {
435+
return err
436+
}
437+
}
438+
439+
return nil
440+
}
441+
442+
func scanPrimitiveCol(rowVal *nebula.Value, val reflect.Value, kind reflect.Kind) error {
443+
switch kind {
444+
case reflect.Bool:
445+
val.SetBool(rowVal.GetBVal())
446+
case reflect.Int:
447+
val.SetInt(rowVal.GetIVal())
448+
case reflect.Int8:
449+
val.SetInt(rowVal.GetIVal())
450+
case reflect.Int16:
451+
val.SetInt(rowVal.GetIVal())
452+
case reflect.Int32:
453+
val.SetInt(rowVal.GetIVal())
454+
case reflect.Int64:
455+
val.SetInt(rowVal.GetIVal())
456+
case reflect.Float32:
457+
val.SetFloat(rowVal.GetFVal())
458+
case reflect.Float64:
459+
val.SetFloat(rowVal.GetFVal())
460+
case reflect.String:
461+
val.SetString(string(rowVal.GetSVal()))
462+
default:
463+
return errors.New("scan: not support primitive type")
464+
}
465+
466+
return nil
467+
}
468+
386469
// Returns the number of total rows
387470
func (res ResultSet) GetRowSize() int {
388471
if res.resp.Data == nil {

0 commit comments

Comments
 (0)