@@ -335,13 +335,13 @@ func (res ResultSet) Scan(v interface{}) error {
335
335
}
336
336
337
337
// 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 ) {
339
339
rowVals := row .GetValues ()
340
340
341
- val := reflect .New (t ).Elem ()
341
+ val := reflect .New (rowType ).Elem ()
342
342
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 )
345
345
tag := f .Tag .Get ("nebula" )
346
346
347
347
if tag == "" {
@@ -356,33 +356,116 @@ func (res ResultSet) scanRow(row *nebula.Row, colNames []string, t reflect.Type)
356
356
357
357
rowVal := rowVals [cIdx ]
358
358
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
+ }
380
370
}
381
371
}
382
372
383
373
return val , nil
384
374
}
385
375
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
+
386
469
// Returns the number of total rows
387
470
func (res ResultSet ) GetRowSize () int {
388
471
if res .resp .Data == nil {
0 commit comments