package ch import ( "context" "reflect" "github.com/uptrace/go-clickhouse/ch/chschema" "github.com/uptrace/go-clickhouse/ch/internal" ) type sliceTableModel struct { db *DB table *chschema.Table slice reflect.Value nextElem func() reflect.Value } var _ TableModel = (*sliceTableModel)(nil) func newSliceTableModel(db *DB, slice reflect.Value, elemType reflect.Type) TableModel { return &sliceTableModel{ db: db, table: chschema.TableForType(elemType), slice: slice, nextElem: internal.MakeSliceNextElemFunc(slice), } } func (m *sliceTableModel) Table() *chschema.Table { return m.table } func (m *sliceTableModel) AppendParam( fmter chschema.Formatter, b []byte, name string, ) ([]byte, bool) { return b, false } func (m *sliceTableModel) ScanBlock(block *chschema.Block) error { for row := 0; row < block.NumRow; row++ { elem := m.nextElem() if err := scanRow(m.db, m.table, elem, block, row); err != nil { return err } } return nil } func (m *sliceTableModel) Block(fields []*chschema.Field) *chschema.Block { sliceLen := m.slice.Len() block := chschema.NewBlock(m.table, len(fields), sliceLen) if sliceLen == 0 { return block } for _, field := range fields { _ = block.ColumnForField(field) } for i := 0; i < sliceLen; i++ { elem := indirect(m.slice.Index(i)) for _, col := range block.Columns { col.AppendValue(col.Field.Value(elem)) } } return block } var _ AfterScanRowHook = (*sliceTableModel)(nil) func (m *sliceTableModel) AfterScanRow(ctx context.Context) error { if m.table.HasAfterScanRowHook() { return callAfterScanRowHookSlice(ctx, m.slice) } return nil }