github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/internal/query/scanner/named.go (about) 1 package scanner 2 3 import ( 4 "fmt" 5 "reflect" 6 7 "github.com/ydb-platform/ydb-go-sdk/v3/internal/value" 8 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors" 9 ) 10 11 type ( 12 NamedScanner struct { 13 data *data 14 } 15 namedDestination struct { 16 name string 17 ref interface{} 18 } 19 NamedDestination interface { 20 Name() string 21 Ref() interface{} 22 } 23 ) 24 25 func (dst namedDestination) Name() string { 26 return dst.name 27 } 28 29 func (dst namedDestination) Ref() interface{} { 30 return dst.ref 31 } 32 33 func NamedRef(columnName string, destinationValueReference interface{}) (dst namedDestination) { 34 if columnName == "" { 35 panic("columnName must be not empty") 36 } 37 dst.name = columnName 38 v := reflect.TypeOf(destinationValueReference) 39 if v.Kind() != reflect.Ptr { 40 panic(fmt.Errorf("%T is not reference type", destinationValueReference)) 41 } 42 dst.ref = destinationValueReference 43 44 return dst 45 } 46 47 func Named(data *data) NamedScanner { 48 return NamedScanner{ 49 data: data, 50 } 51 } 52 53 func (s NamedScanner) ScanNamed(dst ...NamedDestination) (err error) { 54 for i := range dst { 55 v, err := s.data.seekByName(dst[i].Name()) 56 if err != nil { 57 return xerrors.WithStackTrace(err) 58 } 59 if err = value.CastTo(v, dst[i].Ref()); err != nil { 60 return xerrors.WithStackTrace(fmt.Errorf("scan error on column name '%s': %w", dst[i].Name(), err)) 61 } 62 } 63 64 return nil 65 }