gtsocial-umbx

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

model_map_slice.go (2664B)


      1 package bun
      2 
      3 import (
      4 	"context"
      5 	"database/sql"
      6 	"errors"
      7 	"sort"
      8 
      9 	"github.com/uptrace/bun/dialect/feature"
     10 	"github.com/uptrace/bun/schema"
     11 )
     12 
     13 type mapSliceModel struct {
     14 	mapModel
     15 	dest *[]map[string]interface{}
     16 
     17 	keys []string
     18 }
     19 
     20 var _ Model = (*mapSliceModel)(nil)
     21 
     22 func newMapSliceModel(db *DB, dest *[]map[string]interface{}) *mapSliceModel {
     23 	return &mapSliceModel{
     24 		mapModel: mapModel{
     25 			db: db,
     26 		},
     27 		dest: dest,
     28 	}
     29 }
     30 
     31 func (m *mapSliceModel) Value() interface{} {
     32 	return m.dest
     33 }
     34 
     35 func (m *mapSliceModel) SetCap(cap int) {
     36 	if cap > 100 {
     37 		cap = 100
     38 	}
     39 	if slice := *m.dest; len(slice) < cap {
     40 		*m.dest = make([]map[string]interface{}, 0, cap)
     41 	}
     42 }
     43 
     44 func (m *mapSliceModel) ScanRows(ctx context.Context, rows *sql.Rows) (int, error) {
     45 	columns, err := rows.Columns()
     46 	if err != nil {
     47 		return 0, err
     48 	}
     49 
     50 	m.rows = rows
     51 	m.columns = columns
     52 	dest := makeDest(m, len(columns))
     53 
     54 	slice := *m.dest
     55 	if len(slice) > 0 {
     56 		slice = slice[:0]
     57 	}
     58 
     59 	var n int
     60 
     61 	for rows.Next() {
     62 		m.m = make(map[string]interface{}, len(m.columns))
     63 
     64 		m.scanIndex = 0
     65 		if err := rows.Scan(dest...); err != nil {
     66 			return 0, err
     67 		}
     68 
     69 		slice = append(slice, m.m)
     70 		n++
     71 	}
     72 	if err := rows.Err(); err != nil {
     73 		return 0, err
     74 	}
     75 
     76 	*m.dest = slice
     77 	return n, nil
     78 }
     79 
     80 func (m *mapSliceModel) appendColumns(fmter schema.Formatter, b []byte) (_ []byte, err error) {
     81 	if err := m.initKeys(); err != nil {
     82 		return nil, err
     83 	}
     84 
     85 	for i, k := range m.keys {
     86 		if i > 0 {
     87 			b = append(b, ", "...)
     88 		}
     89 		b = fmter.AppendIdent(b, k)
     90 	}
     91 
     92 	return b, nil
     93 }
     94 
     95 func (m *mapSliceModel) appendValues(fmter schema.Formatter, b []byte) (_ []byte, err error) {
     96 	if err := m.initKeys(); err != nil {
     97 		return nil, err
     98 	}
     99 	slice := *m.dest
    100 
    101 	b = append(b, "VALUES "...)
    102 	if m.db.features.Has(feature.ValuesRow) {
    103 		b = append(b, "ROW("...)
    104 	} else {
    105 		b = append(b, '(')
    106 	}
    107 
    108 	if fmter.IsNop() {
    109 		for i := range m.keys {
    110 			if i > 0 {
    111 				b = append(b, ", "...)
    112 			}
    113 			b = append(b, '?')
    114 		}
    115 		return b, nil
    116 	}
    117 
    118 	for i, el := range slice {
    119 		if i > 0 {
    120 			b = append(b, "), "...)
    121 			if m.db.features.Has(feature.ValuesRow) {
    122 				b = append(b, "ROW("...)
    123 			} else {
    124 				b = append(b, '(')
    125 			}
    126 		}
    127 
    128 		for j, key := range m.keys {
    129 			if j > 0 {
    130 				b = append(b, ", "...)
    131 			}
    132 			b = schema.Append(fmter, b, el[key])
    133 		}
    134 	}
    135 
    136 	b = append(b, ')')
    137 
    138 	return b, nil
    139 }
    140 
    141 func (m *mapSliceModel) initKeys() error {
    142 	if m.keys != nil {
    143 		return nil
    144 	}
    145 
    146 	slice := *m.dest
    147 	if len(slice) == 0 {
    148 		return errors.New("bun: map slice is empty")
    149 	}
    150 
    151 	first := slice[0]
    152 	keys := make([]string, 0, len(first))
    153 
    154 	for k := range first {
    155 		keys = append(keys, k)
    156 	}
    157 
    158 	sort.Strings(keys)
    159 	m.keys = keys
    160 
    161 	return nil
    162 }