fixed_string.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package column
  2. import (
  3. "encoding"
  4. "fmt"
  5. "reflect"
  6. "github.com/ClickHouse/clickhouse-go/lib/binary"
  7. )
  8. type FixedString struct {
  9. base
  10. len int
  11. scanType reflect.Type
  12. }
  13. func (str *FixedString) Read(decoder *binary.Decoder, isNull bool) (interface{}, error) {
  14. v, err := decoder.Fixed(str.len)
  15. if err != nil {
  16. return "", err
  17. }
  18. return string(v), nil
  19. }
  20. func (str *FixedString) Write(encoder *binary.Encoder, v interface{}) error {
  21. var fixedString []byte
  22. switch v := v.(type) {
  23. case string:
  24. fixedString = binary.Str2Bytes(v)
  25. case []byte:
  26. fixedString = v
  27. case encoding.BinaryMarshaler:
  28. bytes, err := v.MarshalBinary()
  29. if err != nil {
  30. return err
  31. }
  32. fixedString = bytes
  33. default:
  34. return &ErrUnexpectedType{
  35. T: v,
  36. Column: str,
  37. }
  38. }
  39. switch {
  40. case len(fixedString) > str.len:
  41. return fmt.Errorf("too large value '%s' (expected %d, got %d)", fixedString, str.len, len(fixedString))
  42. case len(fixedString) < str.len:
  43. tmp := make([]byte, str.len)
  44. copy(tmp, fixedString)
  45. fixedString = tmp
  46. }
  47. if _, err := encoder.Write(fixedString); err != nil {
  48. return err
  49. }
  50. return nil
  51. }
  52. func parseFixedString(name, chType string) (*FixedString, error) {
  53. var strLen int
  54. if _, err := fmt.Sscanf(chType, "FixedString(%d)", &strLen); err != nil {
  55. return nil, err
  56. }
  57. return &FixedString{
  58. base: base{
  59. name: name,
  60. chType: chType,
  61. valueOf: columnBaseTypes[string("")],
  62. },
  63. len: strLen,
  64. }, nil
  65. }