Batch: impl `Columns() []column.Interface` method
Hello, my proposal is to provide additional method Columns() []column.Interface for Batch interface. This might be useful when additional information about the table metadata is needed.
Example:
batch, err := chConn.PrepareBatch(ctx, fmt.Sprintf(`INSERT INTO %q`, table))
if err != nil {
return errors.Wrap(err, "ClickHouse: Prepare batch")
}
structType, err := tableSchema(batch.Columns())
if err != nil {
return err
}
func tableSchema(columns []column.Interface) (reflect.Type, error) {
fields := make([]reflect.StructField, len(columns ))
for i, col := range columns {
fieldType := col.ScanType()
name := col.Name()
fields[i] = reflect.StructField{
Name: cases.Title(language.Und).String(name),
Type: fieldType,
Tag: reflect.StructTag(fmt.Sprintf("json:%q ch:%q", name, name)),
}
}
return reflect.StructOf(fields), nil
}
Hi @egsam98
This might be useful when additional information about the table metadata is needed.
What additional data is needed? Perhaps we can try to expose more safe interface.
I suppose the whole information provided by column.Interface might be useful for metaprogramming. As I pointed in example code, by means of Block() I can receive column info like name and Go type from proto.Block. I intentionally made this method returning shallow copy instead of pointer to somehow exclude possible modification. Unfortunately, there's no immutable pointers in Go.
As alternative solution I can replace Block() proto.Block with Columns() []column.Interface. If we speak about safer interface
Personally I use this approach to build dynamic struct via reflect.StructOf and then parse input JSON bytes. Also it would be useful to deal with impossibility to insert Go maps instead of structs:
- Obtain column names from proto.Block in the correct order
- Unwrap the map into slice by iteration for column names
- Use slice for
Batch.Append()method.
Replaced with Columns []column.Interface method
@egsam98 Columns method works for me. Please add a test case that does a simple assertion.
@jkaflik Hi, let me know if I've added test case in a wrong place of codebase. Thank you