gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

model_slice.go (1421B)


      1 package bun
      2 
      3 import (
      4 	"context"
      5 	"database/sql"
      6 	"reflect"
      7 
      8 	"github.com/uptrace/bun/internal"
      9 	"github.com/uptrace/bun/schema"
     10 )
     11 
     12 type sliceInfo struct {
     13 	nextElem func() reflect.Value
     14 	scan     schema.ScannerFunc
     15 }
     16 
     17 type sliceModel struct {
     18 	dest      []interface{}
     19 	values    []reflect.Value
     20 	scanIndex int
     21 	info      []sliceInfo
     22 }
     23 
     24 var _ Model = (*sliceModel)(nil)
     25 
     26 func newSliceModel(db *DB, dest []interface{}, values []reflect.Value) *sliceModel {
     27 	return &sliceModel{
     28 		dest:   dest,
     29 		values: values,
     30 	}
     31 }
     32 
     33 func (m *sliceModel) Value() interface{} {
     34 	return m.dest
     35 }
     36 
     37 func (m *sliceModel) ScanRows(ctx context.Context, rows *sql.Rows) (int, error) {
     38 	columns, err := rows.Columns()
     39 	if err != nil {
     40 		return 0, err
     41 	}
     42 
     43 	m.info = make([]sliceInfo, len(m.values))
     44 	for i, v := range m.values {
     45 		if v.IsValid() && v.Len() > 0 {
     46 			v.Set(v.Slice(0, 0))
     47 		}
     48 
     49 		m.info[i] = sliceInfo{
     50 			nextElem: internal.MakeSliceNextElemFunc(v),
     51 			scan:     schema.Scanner(v.Type().Elem()),
     52 		}
     53 	}
     54 
     55 	if len(columns) == 0 {
     56 		return 0, nil
     57 	}
     58 	dest := makeDest(m, len(columns))
     59 
     60 	var n int
     61 
     62 	for rows.Next() {
     63 		m.scanIndex = 0
     64 		if err := rows.Scan(dest...); err != nil {
     65 			return 0, err
     66 		}
     67 		n++
     68 	}
     69 	if err := rows.Err(); err != nil {
     70 		return 0, err
     71 	}
     72 
     73 	return n, nil
     74 }
     75 
     76 func (m *sliceModel) Scan(src interface{}) error {
     77 	info := m.info[m.scanIndex]
     78 	m.scanIndex++
     79 
     80 	dest := info.nextElem()
     81 	return info.scan(dest, src)
     82 }