rowbinary

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 13, 2025 License: MIT Imports: 28 Imported by: 0

README

Features

  • HTTP client with Select, Insert, Exec methods
  • RowBinary, RowBinaryWithNames and RowBinaryWithNamesAndTypes formats are supported
  • WithDiscovery option for easy integration with Service Discovery
  • Zero-reflection generic-based types
  • You can implement your own Go type for a ClickHouse type. Example type and tests
  • External data is supported

Usage

Select

err := client.Select(ctx,
    "SELECT * FROM table LIMIT 10",
    rowbinary.WithFormatReader(func(r *rowbinary.FormatReader) error {
    for r.Next() {
        var value string
        if err := rowbinary.Scan(r, rowbinary.String, &value); err != nil {
            return err
        }
        // process value
    }
    return r.Err()
}))

Insert

err := client.Insert(ctx, "table",
    rowbinary.C("column", rowbinary.String),
    rowbinary.WithFormatWriter(func(w *rowbinary.FormatWriter) error {
    for _, value := range values {
        if err := rowbinary.Write(w, rowbinary.String, value); err != nil {
            return err
        }
    }
    return nil
}))

Exec

err := client.Exec(ctx, "CREATE TABLE table (id UInt64) ENGINE = MergeTree() ORDER BY id")

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	BinaryTypeNothing                 = [1]byte{0x00}
	BinaryTypeUInt8                   = [1]byte{0x01}
	BinaryTypeUInt16                  = [1]byte{0x02}
	BinaryTypeUInt32                  = [1]byte{0x03}
	BinaryTypeUInt64                  = [1]byte{0x04}
	BinaryTypeUInt128                 = [1]byte{0x05}
	BinaryTypeUInt256                 = [1]byte{0x06}
	BinaryTypeInt8                    = [1]byte{0x07}
	BinaryTypeInt16                   = [1]byte{0x08}
	BinaryTypeInt32                   = [1]byte{0x09}
	BinaryTypeInt64                   = [1]byte{0x0A}
	BinaryTypeInt128                  = [1]byte{0x0B}
	BinaryTypeInt256                  = [1]byte{0x0C}
	BinaryTypeFloat32                 = [1]byte{0x0D}
	BinaryTypeFloat64                 = [1]byte{0x0E}
	BinaryTypeDate                    = [1]byte{0x0F}
	BinaryTypeDate32                  = [1]byte{0x10}
	BinaryTypeDateTime                = [1]byte{0x11}
	BinaryTypeDateTimeWithTimeZone    = [1]byte{0x12} // <var_uint_time_zone_name_size><time_zone_name_data>
	BinaryTypeDateTime64              = [1]byte{0x13} // <uint8_precision>
	BinaryTypeDateTime64WithTimeZone  = [1]byte{0x14} // <uint8_precision><var_uint_time_zone_name_size><time_zone_name_data>
	BinaryTypeString                  = [1]byte{0x15}
	BinaryTypeFixedString             = [1]byte{0x16} // <var_uint_size>
	BinaryTypeEnum8                   = [1]byte{0x17} // <var_uint_number_of_elements><var_uint_name_size_1><name_data_1><int8_value_1>...<var_uint_name_size_N><name_data_N><int8_value_N>
	BinaryTypeEnum16                  = [1]byte{0x18} // <var_uint_number_of_elements><var_uint_name_size_1><name_data_1><int16_little_endian_value_1>...><var_uint_name_size_N><name_data_N><int16_little_endian_value_N>
	BinaryTypeDecimal32               = [1]byte{0x19} // <uint8_precision><uint8_scale>
	BinaryTypeDecimal64               = [1]byte{0x1A} // <uint8_precision><uint8_scale>
	BinaryTypeDecimal128              = [1]byte{0x1B} // <uint8_precision><uint8_scale>
	BinaryTypeDecimal256              = [1]byte{0x1C} // <uint8_precision><uint8_scale>
	BinaryTypeUUID                    = [1]byte{0x1D}
	BinaryTypeArray                   = [1]byte{0x1E} // <nested_type_encoding>
	BinaryTypeTuple                   = [1]byte{0x1F} // <var_uint_number_of_elements><nested_type_encoding_1>...<nested_type_encoding_N>
	BinaryTypeTupleNamed              = [1]byte{0x20} // <var_uint_number_of_elements><var_uint_name_size_1><name_data_1><nested_type_encoding_1>...<var_uint_name_size_N><name_data_N><nested_type_encoding_N>
	BinaryTypeSet                     = [1]byte{0x21}
	BinaryTypeInterval                = [1]byte{0x22} // <interval_kind> (see interval kind binary encoding)
	BinaryTypeNullable                = [1]byte{0x23} // <nested_type_encoding>
	BinaryTypeFunction                = [1]byte{0x24} // <var_uint_number_of_arguments><argument_type_encoding_1>...<argument_type_encoding_N><return_type_encoding>
	BinaryTypeAggregateFunction       = [1]byte{0x25} // <var_uint_version><var_uint_function_name_size><function_name_data><var_uint_number_of_parameters><param_1>...<param_N><var_uint_number_of_arguments><argument_type_encoding_1>...<argument_type_encoding_N> (see aggregate function parameter binary encoding)
	BinaryTypeLowCardinality          = [1]byte{0x26} // <nested_type_encoding>
	BinaryTypeMap                     = [1]byte{0x27} // <key_type_encoding><value_type_encoding>
	BinaryTypeIPv4                    = [1]byte{0x28}
	BinaryTypeIPv6                    = [1]byte{0x29}
	BinaryTypeVariant                 = [1]byte{0x2A} // <var_uint_number_of_variants><variant_type_encoding_1>...<variant_type_encoding_N>
	BinaryTypeDynamic                 = [1]byte{0x2B} // <uint8_max_types>
	BinaryTypeCustom                  = [1]byte{0x2C} // <var_uint_type_name_size><type_name_data>
	BinaryTypeBool                    = [1]byte{0x2D}
	BinaryTypeSimpleAggregateFunction = [1]byte{0x2E} // <var_uint_function_name_size><function_name_data><var_uint_number_of_parameters><param_1>...<param_N><var_uint_number_of_arguments><argument_type_encoding_1>...<argument_type_encoding_N> (see aggregate function parameter binary encoding)
	BinaryTypeNested                  = [1]byte{0x2F} // <var_uint_number_of_elements><var_uint_name_size_1><name_data_1><nested_type_encoding_1>...<var_uint_name_size_N><name_data_N><nested_type_encoding_N>
	BinaryTypeJSON                    = [1]byte{0x30} // <uint8_serialization_version><var_int_max_dynamic_paths><uint8_max_dynamic_types><var_uint_number_of_typed_paths><var_uint_path_name_size_1><path_name_data_1><encoded_type_1>...<var_uint_number_of_skip_paths><var_uint_skip_path_size_1><skip_path_data_1>...<var_uint_number_of_skip_path_regexps><var_uint_skip_path_regexp_size_1><skip_path_data_regexp_1>...
	BinaryTypeBFloat16                = [1]byte{0x31}
	BinaryTypeTime                    = [1]byte{0x32}
	BinaryTypeTime64                  = [1]byte{0x34} // <uint8_precision>
)
View Source
var NotImplementedError = errors.New("not implemented")

Functions

func BenchmarkType

func BenchmarkType[T any](b *testing.B, tp Type[T], value T)

func Eq

func Eq(a, b Any) bool

func ExecLocal

func ExecLocal(query string) ([]byte, error)

ExecLocal executes a ClickHouse query locally using the 'clickhouse local' command and caches the result to disk.

It takes a query string as input, computes a SHA256 hash of the query to generate a unique filename, and stores the result in the 'fixtures/' directory. If the result is already cached, it reads from the file instead of re-executing the query. This is primarily used for testing purposes to avoid repeated executions of the same query, especially in CI environments where fixtures can be committed.

Parameters:

  • query: The ClickHouse query string to execute.

Returns:

  • []byte: The binary output of the query.
  • error: An error if the command fails or file operations encounter issues.

Note: The function assumes 'clickhouse' is available in the system PATH. The query is executed with default settings unless specified in the query string.

func NewInvalidTypeError

func NewInvalidTypeError(msg string) error

func Scan

func Scan[V any](r *FormatReader, tp Type[V], v *V) error

func SetGlobalDiscovery

func SetGlobalDiscovery(callback func(ctx context.Context, dsn string, kind DiscoveryCtx) (string, error))

func StringEncode

func StringEncode(s string) []byte

func StringWrite

func StringWrite(w Writer, value string) error

func TestType

func TestType[T any](t *testing.T, tp Type[T], value T, query string)

func VarintEncode

func VarintEncode(x uint64) []byte

func VarintRead

func VarintRead(r Reader) (uint64, error)

func VarintWrite

func VarintWrite(w Writer, x uint64) error

func WithDSN

func WithDSN(dsn string) dsnOption

WithDSN sets the DSN for the request.

func WithDatabase

func WithDatabase(database string) paramOption

WithDatabase sets the database for the client.

func WithExternalData

func WithExternalData(name string, cb func(w *FormatWriter) error, opts ...ExternalDataOption) externalData

func WithHeader

func WithHeader(name, value string) headerOption

func WithParam

func WithParam(name, value string) paramOption

func WithUseBinaryHeader

func WithUseBinaryHeader(value bool) useBinaryHeaderType

func Write

func Write[V any](w *FormatWriter, tp Type[V], value V) error

Types

type Any

type Any interface {
	String() string
	Binary() []byte
	ScanAny(r Reader, v any) error
	WriteAny(w Writer, v any) error
	ID() uint64
}

func DecodeBinaryType

func DecodeBinaryType(r Reader) (Any, error)

DecodeBinaryType decodes a binary type from the given reader.

func DecodeStringType

func DecodeStringType(t string) (Any, error)

DecodeStringType decodes a string type from the given reader.

type BaseType

type BaseType[T any] interface {
	String() string
	Binary() []byte // https://clickhouse.com/docs/sql-reference/data-types/data-types-binary-encoding
	Write(w Writer, v T) error
	Scan(r Reader, v *T) error
}

type Client

type Client interface {
	// Select executes a SELECT query against the ClickHouse server and processes the response using the provided read function.
	//
	// It sends the query to ClickHouse, receives the result in RowBinary format (or variants), and invokes the readFunc
	// with a FormatReader to parse the data. The method supports various options for customizing the query format,
	// adding external data, parameters, and headers.
	//
	// Parameters:
	//   - ctx: Context for the request, used for cancellation and timeouts.
	//   - query: The SQL SELECT query string to execute.
	//   - readFunc: A callback function that receives a FormatReader to read and process the query results.
	//   - options: Optional SelectOption values to configure the query (e.g., format, external data, params).
	//
	// Returns:
	//   - error: An error if the request fails, the response status is not OK, or reading/parsing encounters issues.
	//
	// Note: The query results are streamed and processed incrementally via the readFunc. For external data,
	// the method uses multipart/form-data encoding. Default select options from the client configuration are applied first.
	Select(ctx context.Context, query string, options ...SelectOption) error

	// Exec executes an arbitrary SQL query (e.g., CREATE, DROP, ALTER) against the ClickHouse server.
	//
	// It sends the query as the request body and ensures the operation completes successfully.
	// This method is suitable for queries that do not return data, such as DDL statements or updates.
	//
	// Parameters:
	//   - ctx: Context for the request, used for cancellation and timeouts.
	//   - query: The SQL query string to execute.
	//   - options: Optional ExecOption values to configure the query (e.g., params, headers).
	//
	// Returns:
	//   - error: An error if the request fails or the response status is not OK.
	//
	// Note: Default exec options from the client configuration are applied first.
	// For queries that return data, use Select instead. For inserting data, use Insert.
	Exec(ctx context.Context, query string, options ...ExecOption) error

	// Insert executes an INSERT query into the specified ClickHouse table by writing data using the provided write function.
	//
	// It constructs an INSERT INTO query with the specified format, streams the data written by writeFunc to the server,
	// and ensures the operation completes successfully. The data is written incrementally via the FormatWriter.
	//
	// Parameters:
	//   - ctx: Context for the request, used for cancellation and timeouts.
	//   - table: The name of the ClickHouse table to insert data into.
	//   - writeFunc: A callback function that receives a FormatWriter to write the data to be inserted.
	//   - options: Optional InsertOption values to configure the insert (e.g., format, params, headers).
	//
	// Returns:
	//   - error: An error if the request fails, writing data encounters issues, or the response status is not OK.
	//
	// Note: The data is streamed to the server as it's written by writeFunc. Default insert options from the client
	// configuration are applied first. The format header is automatically written before invoking writeFunc.
	Insert(ctx context.Context, table string, options ...InsertOption) error

	Close() error
}

Client defines the interface for interacting with a ClickHouse database server.

It provides methods for executing SELECT queries to retrieve data, INSERT queries to add data, and general EXEC queries for DDL operations or updates. Implementations handle connection management, query execution, and data serialization in RowBinary format.

The interface is designed to be used with context for cancellation and timeouts, and supports various options for customizing query behavior, such as format specifications, parameters, and headers.

func NewClient

func NewClient(ctx context.Context, options ...ClientOption) Client

NewClient creates a new ClickHouse client.

type ClientMethod

type ClientMethod int
const (
	ClientMethodSelect  ClientMethod = 1
	ClientMethodInsert  ClientMethod = 2
	ClientMethodExecute ClientMethod = 3
)

type ClientOption

type ClientOption interface {
	// contains filtered or unexported methods
}

func WithDiscovery

func WithDiscovery(discovery func(ctx context.Context, dsn string, kind DiscoveryCtx) (string, error)) ClientOption

WithDiscovery sets the discovery function for the ClickHouse client.

func WithHTTPClient

func WithHTTPClient(httpClient *http.Client) ClientOption

WithHTTPClient sets the HTTP client for the ClickHouse client.

type Column

type Column struct {
	// contains filtered or unexported fields
}

func C

func C(name string, tp Any) Column

func WithColumn

func WithColumn(name string, tp Any) Column

func (Column) Name

func (c Column) Name() string

func (Column) String

func (c Column) String() string

func (Column) Type

func (c Column) Type() Any

type Columns

type Columns struct {
	// contains filtered or unexported fields
}

func (Columns) At

func (c Columns) At(i int) Column

func (Columns) Len

func (c Columns) Len() int

type DiscoveryCtx

type DiscoveryCtx struct {
	Method ClientMethod
}

type ExecOption

type ExecOption interface {
	// contains filtered or unexported methods
}

type ExternalDataOption

type ExternalDataOption interface {
	// contains filtered or unexported methods
}

type Format

type Format int
const (
	RowBinary                  Format = 0
	RowBinaryWithNames         Format = 1
	RowBinaryWithNamesAndTypes Format = 2
)

func (Format) Eq

func (f Format) Eq(other Format) bool

func (Format) In

func (f Format) In(other ...Format) bool

func (Format) String

func (f Format) String() string

type FormatOption

type FormatOption interface {
	// contains filtered or unexported methods
}

type FormatReader

type FormatReader struct {
	// contains filtered or unexported fields
}

func NewFormatReader

func NewFormatReader(wrap io.Reader, opts ...FormatOption) *FormatReader

func (*FormatReader) Column

func (r *FormatReader) Column(i int) (Column, error)

func (*FormatReader) Columns

func (r *FormatReader) Columns() (*Columns, error)

func (*FormatReader) Err

func (r *FormatReader) Err() error

func (*FormatReader) Next

func (r *FormatReader) Next() bool

func (*FormatReader) Scan

func (r *FormatReader) Scan(dest ...any) error

type FormatWriter

type FormatWriter struct {
	// contains filtered or unexported fields
}

func NewFormatWriter

func NewFormatWriter(wrap io.Writer, opts ...FormatOption) *FormatWriter

func (*FormatWriter) Err

func (w *FormatWriter) Err() error

func (*FormatWriter) Format

func (w *FormatWriter) Format() Format

func (*FormatWriter) Structure

func (w *FormatWriter) Structure() string

func (*FormatWriter) WriteAny

func (w *FormatWriter) WriteAny(values ...any) error

func (*FormatWriter) WriteHeader

func (w *FormatWriter) WriteHeader() error

type InsertOption

type InsertOption interface {
	// contains filtered or unexported methods
}

func WithBodyWriter

func WithBodyWriter(bw func(w io.Writer) error) InsertOption

func WithFormatWriter

func WithFormatWriter(fw func(w *FormatWriter) error) InsertOption

type InvalidTypeError

type InvalidTypeError struct {
	Msg string
}

func (InvalidTypeError) Error

func (e InvalidTypeError) Error() string

type KV

type KV[K comparable, V any] struct {
	// contains filtered or unexported fields
}

func NewKV

func NewKV[K comparable, V any]() *KV[K, V]

func (*KV[K, V]) Append

func (kv *KV[K, V]) Append(key K, value V) *KV[K, V]

func (*KV[K, V]) Delete

func (kv *KV[K, V]) Delete(key K) *KV[K, V]

func (*KV[K, V]) Each

func (kv *KV[K, V]) Each(f func(key K, value V) error) error

func (*KV[K, V]) Get

func (kv *KV[K, V]) Get(key K) (V, bool)

func (*KV[K, V]) Len

func (kv *KV[K, V]) Len() int

func (*KV[K, V]) Reset

func (kv *KV[K, V]) Reset() *KV[K, V]

func (*KV[K, V]) Set

func (kv *KV[K, V]) Set(key K, value V) *KV[K, V]

type PreType

type PreType[T any] interface {
	BaseType[T]
	WriteAny(w Writer, v any) error
	ScanAny(r Reader, v any) error
}

func WrapAny

func WrapAny[T any](tp BaseType[T]) PreType[T]

type Reader

type Reader interface {
	io.Reader
	io.ByteScanner
	Peek(n int) ([]byte, error)
	Discard(n int) (discarded int, err error)
}

func NewReader

func NewReader(r io.Reader) Reader

type SelectOption

type SelectOption interface {
	// contains filtered or unexported methods
}

func WithBodyReader

func WithBodyReader(cb func(r io.Reader) error) SelectOption

func WithFormatReader

func WithFormatReader(cb func(r *FormatReader) error) SelectOption

type TestClient

type TestClient struct {
	Client
	// contains filtered or unexported fields
}

func NewTestClient

func NewTestClient(ctx context.Context, dsn string, options ...ClientOption) *TestClient

NewTestClient creates a new test client with an isolated database for testing purposes.

It generates a unique database name using an atomic counter and current timestamp, creates a new ClickHouse client connected to that database, and executes a CREATE DATABASE command to ensure the database exists. The client is configured with the provided DSN and options, and the database is set to the newly created one.

Parameters:

  • ctx: Context for the client creation.
  • dsn: Data Source Name for connecting to ClickHouse.
  • options: Optional client configuration options.

Returns:

  • Client: A test client instance that wraps the standard Client with database isolation. The client automatically manages the database lifecycle.

Note: The function will log.Fatal if database creation fails. The returned client should be closed using its Close method to drop the database.

func (*TestClient) Close

func (tc *TestClient) Close() error

func (*TestClient) Database

func (tc *TestClient) Database() string

type Type

type Type[T any] interface {
	PreType[T]
	ID() uint64
}
var Bool Type[bool] = MakeTypeWrapAny[bool](typeBool{})
var Date Type[ValueDate] = MakeTypeWrapAny[ValueDate](typeDate{})
var Date32 Type[ValueDate] = MakeTypeWrapAny[ValueDate](typeDate32{})
var DateTime Type[time.Time] = MakeTypeWrapAny[time.Time](typeDateTime{})
var Float32 Type[float32] = MakeTypeWrapAny[float32](typeFloat32{})
var Float64 Type[float64] = MakeTypeWrapAny[float64](typeFloat64{})
var IPv4 Type[[4]byte] = MakeTypeWrapAny[[4]byte](typeIPv4{})
var IPv6 Type[[16]byte] = MakeTypeWrapAny[[16]byte](typeIPv6{})
var Int16 Type[int16] = MakeTypeWrapAny[int16](typeInt16{})
var Int32 Type[int32] = MakeTypeWrapAny[int32](typeInt32{})
var Int64 Type[int64] = MakeTypeWrapAny[int64](typeInt64{})
var Int8 Type[int8] = MakeTypeWrapAny[int8](typeInt8{})
var IntervalDay Type[int64] = MakeTypeWrapAny[int64](typeInterval{kind: intervalKindDay})
var IntervalHour Type[int64] = MakeTypeWrapAny[int64](typeInterval{kind: intervalKindHour})
var IntervalMicrosecond Type[int64] = MakeTypeWrapAny[int64](typeInterval{kind: intervalKindMicrosecond})
var IntervalMillisecond Type[int64] = MakeTypeWrapAny[int64](typeInterval{kind: intervalKindMillisecond})
var IntervalMinute Type[int64] = MakeTypeWrapAny[int64](typeInterval{kind: intervalKindMinute})
var IntervalMonth Type[int64] = MakeTypeWrapAny[int64](typeInterval{kind: intervalKindMonth})
var IntervalNanosecond Type[int64] = MakeTypeWrapAny[int64](typeInterval{kind: intervalKindNanosecond})
var IntervalQuarter Type[int64] = MakeTypeWrapAny[int64](typeInterval{kind: intervalKindQuarter})
var IntervalSecond Type[int64] = MakeTypeWrapAny[int64](typeInterval{kind: intervalKindSecond})
var IntervalWeek Type[int64] = MakeTypeWrapAny[int64](typeInterval{kind: intervalKindWeek})
var IntervalYear Type[int64] = MakeTypeWrapAny[int64](typeInterval{kind: intervalKindYear})
var Nothing Type[any] = MakeTypeWrapAny[any](typeNothing{})
var Point Type[[]any] = Custom("Point", TupleAny(Float64, Float64))
var String Type[string] = MakeTypeWrapAny[string](typeString{})
var StringBytes Type[[]byte] = MakeTypeWrapAny[[]byte](typeStringBytes{})
var UInt16 Type[uint16] = MakeTypeWrapAny[uint16](typeUInt16{})
var UInt32 Type[uint32] = MakeTypeWrapAny[uint32](typeUInt32{})
var UInt64 Type[uint64] = MakeTypeWrapAny[uint64](typeUInt64{})
var UInt8 Type[uint8] = MakeTypeWrapAny[uint8](typeUInt8{})
var UUID Type[uuid.UUID] = MakeTypeWrapAny[uuid.UUID](typeUUID{})

func Array

func Array[V any](valueType Type[V]) Type[[]V]

func ArrayAny

func ArrayAny(valueType Any) Type[[]any]

func Custom

func Custom[T any](name string, base Type[T]) Type[T]

func DateTime64

func DateTime64(p uint8) Type[time.Time]

func DateTime64TZ

func DateTime64TZ(p uint8, tz string) Type[time.Time]

func DateTimeTZ

func DateTimeTZ(tz string) Type[time.Time]

func Decimal

func Decimal(precision uint8, scale uint8) Type[decimal.Decimal]

func Decimal128

func Decimal128(precision uint8, scale uint8) Type[decimal.Decimal]

func Decimal256

func Decimal256(precision uint8, scale uint8) Type[decimal.Decimal]

func Decimal32

func Decimal32(precision uint8, scale uint8) Type[decimal.Decimal]

func Decimal64

func Decimal64(precision uint8, scale uint8) Type[decimal.Decimal]

func Dynamic

func Dynamic(maxTypes uint8, knownTypes ...Any) Type[Value]

func Enum16

func Enum16(v map[string]int16) Type[string]

func Enum8

func Enum8(v map[string]int8) Type[string]

func FixedString

func FixedString(length int) Type[[]byte]

func Invalid

func Invalid[T any](msg string) Type[T]

func LowCardinality

func LowCardinality[V any](valueType Type[V]) Type[V]

func LowCardinalityAny

func LowCardinalityAny(valueType Any) Type[any]

func MakeType

func MakeType[T any](tp PreType[T]) Type[T]

func MakeTypeWrapAny

func MakeTypeWrapAny[T any](tp BaseType[T]) Type[T]

func Map

func Map[K comparable, V any](keyType Type[K], valueType Type[V]) Type[map[K]V]

Map creates a Type for encoding and decoding maps in RowBinary format.

It constructs a type handler for maps with keys of type K and values of type V, using the provided keyType and valueType for serialization. The map is encoded as a sequence of key-value pairs, preceded by the number of entries as a UVarint.

Parameters:

  • keyType: The Type handler for the map keys (K must be comparable).
  • valueType: The Type handler for the map values.

Returns:

  • Type[map[K]V]: A type instance that can read/write maps in RowBinary format.

Note: The order of key-value pairs in the encoded output is not guaranteed to match the iteration order of the map, as Go maps are unordered.

func MapAny

func MapAny(keyType Any, valueType Any) Type[map[any]any]

MapAny creates a Type for encoding and decoding maps with dynamic types in RowBinary format.

It constructs a type handler for maps where keys and values are of type 'any', using the provided Any type handlers for serialization. This allows for heterogeneous key-value pairs where types are determined at runtime. The map is encoded as a sequence of key-value pairs, preceded by the number of entries as a UVarint.

Parameters:

  • keyType: The Any type handler for the map keys.
  • valueType: The Any type handler for the map values.

Returns:

  • Type[map[any]any]: A type instance that can read/write maps with dynamic types in RowBinary format.

Note: Since keys and values are 'any', type safety is not enforced at compile time. Ensure that the provided Any types match the actual data types to avoid runtime errors. The order of key-value pairs in the encoded output is not guaranteed.

func MapKV

func MapKV[K comparable, V any](keyType Type[K], valueType Type[V]) Type[*KV[K, V]]

func Nullable

func Nullable[V any](valueType Type[V]) Type[*V]

Nullable creates a Type for encoding and decoding nullable values in RowBinary format.

It constructs a type handler for values that can be nil, represented as a pointer to V. In RowBinary, nullable values are encoded with a leading byte: 0x01 indicates null, and 0x00 indicates a present value followed by the value's encoding.

Parameters:

  • valueType: The Type handler for the underlying value type V.

Returns:

  • Type[*V]: A type instance that can read/write nullable values in RowBinary format.

Note: Use a pointer (*V) to represent nullable values. A nil pointer encodes as null, and a non-nil pointer encodes the dereferenced value.

func NullableAny

func NullableAny(valueType Any) Type[*any]

NullableAny creates a Type for encoding and decoding nullable values with dynamic types in RowBinary format.

It constructs a type handler for values that can be nil, represented as a pointer to 'any'. This allows for nullable values where the type is determined at runtime. In RowBinary, nullable values are encoded with a leading byte: 0x01 indicates null, and 0x00 indicates a present value followed by the value's encoding using the provided Any type handler.

Parameters:

  • valueType: The Any type handler for the underlying value type.

Returns:

  • Type[*any]: A type instance that can read/write nullable values with dynamic types in RowBinary format.

Note: Use a pointer (*any) to represent nullable values. A nil pointer encodes as null, and a non-nil pointer encodes the dereferenced value. Type safety is not enforced at compile time.

func TupleAny

func TupleAny(valueTypes ...Any) Type[[]any]

TupleAny creates a Type for encoding and decoding tuples with dynamic types in RowBinary format.

It constructs a type handler for tuples where each element can have a different type, represented as a slice of 'any'. The tuple is encoded as a sequence of values in the order of the provided Any type handlers. The number of elements must match the number of valueTypes.

Parameters:

  • valueTypes: A variadic list of Any type handlers for each tuple element.

Returns:

  • Type[[]any]: A type instance that can read/write tuples with dynamic types in RowBinary format.

Note: The length of the slice must exactly match the number of valueTypes. Type safety is not enforced at compile time; ensure the data matches the provided Any types to avoid runtime errors.

func TupleNamedAny

func TupleNamedAny(columns ...Column) Type[[]any]

TupleNamedAny creates a Type for encoding and decoding named tuples with dynamic types in RowBinary format.

It constructs a type handler for tuples where each element has a name and type, represented as a slice of 'any'. The tuple is encoded as a sequence of values in the order of the provided columns. The number of elements in the slice must match the number of columns.

Parameters:

  • columns: A variadic list of Column definitions, each containing a name and Any type handler.

Returns:

  • Type[[]any]: A type instance that can read/write named tuples with dynamic types in RowBinary format.

Note: The length of the slice must exactly match the number of columns. Column names are used for metadata but do not affect the binary encoding. Type safety is not enforced at compile time.

func Variant

func Variant(valueTypes ...Any) Type[Value]

type TypeMismatchError

type TypeMismatchError struct {
	ExpectedType string
	ActualType   string
}

func (TypeMismatchError) Error

func (e TypeMismatchError) Error() string

type Value

type Value struct {
	Type  Any
	Value any
}

func (Value) String

func (v Value) String() string

type ValueDate

type ValueDate struct {
	Year  uint16
	Month uint8
	Day   uint8
}

type Writer

type Writer interface {
	io.Writer
	io.ByteWriter
	Buffer() []byte // 16 bytes buffer for encoding
}

func NewWriter

func NewWriter(w io.Writer) Writer

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL