github.com/aacfactory/fns-contrib/databases/sql@v1.2.84/dac/specifications/scanner.go (about)

     1  package specifications
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/aacfactory/errors"
     6  	"reflect"
     7  	"sync"
     8  )
     9  
    10  var (
    11  	genericsPool = sync.Pool{}
    12  )
    13  
    14  func acquireGenerics(n int) (v Generics) {
    15  	c := genericsPool.Get()
    16  	if c == nil {
    17  		v = make(Generics, n)
    18  		for i := 0; i < n; i++ {
    19  			v[i] = &Generic{}
    20  		}
    21  	} else {
    22  		v = c.(Generics)
    23  		vLen := len(v)
    24  		if delta := n - vLen; delta < 0 {
    25  			v = v[0:n]
    26  		} else if delta > 0 {
    27  			for i := 0; i < delta; i++ {
    28  				v = append(v, &Generic{})
    29  			}
    30  		}
    31  	}
    32  	return
    33  }
    34  
    35  func releaseGenerics(generics Generics) {
    36  	for _, generic := range generics {
    37  		generic.(*Generic).Reset()
    38  	}
    39  	genericsPool.Put(generics)
    40  }
    41  
    42  type Generics []any
    43  
    44  func (generics Generics) WriteTo(spec *Specification, fieldNames []string, entryPtr any) (err error) {
    45  	rv := reflect.Indirect(reflect.ValueOf(entryPtr))
    46  	for i, fieldName := range fieldNames {
    47  		column, has := spec.ColumnByField(fieldName)
    48  		if !has {
    49  			err = errors.Warning(fmt.Sprintf("sql: %s field was not found in %s", fieldName, spec.Key)).
    50  				WithMeta("field", fieldName).WithMeta("table", spec.Key)
    51  			return
    52  		}
    53  		fv := column.ReadValue(rv)
    54  		generic := generics[i].(*Generic)
    55  		if generic.Valid {
    56  			err = column.WriteValue(fv, generic.Value)
    57  			if err != nil {
    58  				err = errors.Warning(fmt.Sprintf("sql: write value into %s.%s field failed", spec.Key, fieldName)).WithCause(err).
    59  					WithMeta("field", fieldName).WithMeta("table", spec.Key)
    60  				return
    61  			}
    62  		}
    63  	}
    64  	return
    65  }
    66  
    67  type Generic struct {
    68  	Valid bool
    69  	Value any
    70  }
    71  
    72  func (v *Generic) Scan(src any) (err error) {
    73  	if src == nil {
    74  		return
    75  	}
    76  	v.Valid = true
    77  	v.Value = src
    78  	return
    79  }
    80  
    81  func (v *Generic) Reset() {
    82  	v.Valid = false
    83  	v.Value = nil
    84  }