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  }