github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/depends/kit/sqlx/scanner/scan_iter.go (about)

     1  package scanner
     2  
     3  import (
     4  	"reflect"
     5  
     6  	"github.com/machinefi/w3bstream/pkg/depends/x/reflectx"
     7  )
     8  
     9  type ScanIterator interface {
    10  	// New a ptr value for scan
    11  	New() interface{}
    12  	// Next for receive scanned value
    13  	Next(v interface{}) error
    14  }
    15  
    16  func ScanIteratorFor(v interface{}) (ScanIterator, error) {
    17  	switch x := v.(type) {
    18  	case ScanIterator:
    19  		return x, nil
    20  	default:
    21  		t := reflectx.DeRef(reflect.TypeOf(v))
    22  		if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {
    23  			return &SliceScanIterator{
    24  				t.Elem(), reflectx.Indirect(reflect.ValueOf(v)),
    25  			}, nil
    26  		}
    27  		return &SingleScanIterator{v: v}, nil
    28  	}
    29  }
    30  
    31  type SliceScanIterator struct {
    32  	t reflect.Type
    33  	v reflect.Value
    34  }
    35  
    36  func (s *SliceScanIterator) New() interface{} {
    37  	return reflectx.New(s.t).Addr().Interface()
    38  }
    39  
    40  func (s *SliceScanIterator) Next(v interface{}) error {
    41  	s.v.Set(reflect.Append(s.v, reflect.ValueOf(v).Elem()))
    42  	return nil
    43  }
    44  
    45  type SingleScanIterator struct {
    46  	v          interface{}
    47  	hasResults bool
    48  }
    49  
    50  func (s *SingleScanIterator) New() interface{} {
    51  	return s.v
    52  }
    53  
    54  func (s *SingleScanIterator) Next(v interface{}) error {
    55  	s.hasResults = true
    56  	return nil
    57  }
    58  
    59  func (s *SingleScanIterator) HasRecord() bool { return s.hasResults }