1
0
mirror of https://github.com/uptrace/go-clickhouse.git synced 2025-06-08 23:26:11 +02:00
go-clickhouse/ch/model_table_slice.go

79 lines
1.6 KiB
Go
Raw Normal View History

2022-01-23 09:36:24 +02:00
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
}