mirror of
https://github.com/uptrace/go-clickhouse.git
synced 2025-06-08 23:26:11 +02:00
79 lines
1.6 KiB
Go
79 lines
1.6 KiB
Go
|
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
|
||
|
}
|