diff --git a/internal/params/builder.go b/internal/params/builder.go index ce8421fb0..b7096cf20 100644 --- a/internal/params/builder.go +++ b/internal/params/builder.go @@ -1,11 +1,23 @@ package params +import ( + "github.com/ydb-platform/ydb-go-sdk/v3/internal/value" +) + type ( Builder struct { params Parameters } ) +func (b Builder) append(name string, value value.Value) { + b.params = append(b.params, &Parameter{ + parent: b, + name: name, + value: value, + }) +} + func (b Builder) Build() *Parameters { return &b.params } diff --git a/internal/params/list.go b/internal/params/list.go index c577c824d..41ecbe58a 100644 --- a/internal/params/list.go +++ b/internal/params/list.go @@ -7,166 +7,182 @@ import ( ) type ( - list struct { - parent Builder + listParent interface { + append(name string, value value.Value) + } + list[T listParent] struct { + parent T name string values []value.Value } - listItem struct { - parent *list + listItemParent interface { + appendItem(value value.Value) + } + listItem[T listItemParent] struct { + parent T } ) -func (l *list) Add() *listItem { - return &listItem{ +func (l *list[T]) appendItem(value value.Value) { + l.values = append(l.values, value) +} + +func (l *list[T]) append(name string, value value.Value) { + l.parent.append(name, value) +} + +func (l *list[T]) Add() *listItem[*list[T]] { + return &listItem[*list[T]]{ parent: l, } } -func (l *list) AddItems(items ...value.Value) *list { +func (l *list[T]) AddItems(items ...value.Value) *list[T] { l.values = append(l.values, items...) return l } -func (l *list) EndList() Builder { - l.parent.params = append(l.parent.params, &Parameter{ - parent: l.parent, - name: l.name, - value: value.ListValue(l.values...), - }) +func (l *list[T]) BeginList() *list[*list[T]] { + return &list[*list[T]]{ + parent: l, + } +} + +func (l *list[T]) EndList() T { + l.parent.append(l.name, value.ListValue(l.values...)) return l.parent } -func (l *listItem) Text(v string) *list { - l.parent.values = append(l.parent.values, value.TextValue(v)) +func (l listItem[T]) Text(v string) T { + l.parent.appendItem(value.TextValue(v)) return l.parent } -func (l *listItem) Bytes(v []byte) *list { - l.parent.values = append(l.parent.values, value.BytesValue(v)) +func (l listItem[T]) Bytes(v []byte) T { + l.parent.appendItem(value.BytesValue(v)) return l.parent } -func (l *listItem) Bool(v bool) *list { - l.parent.values = append(l.parent.values, value.BoolValue(v)) +func (l listItem[T]) Bool(v bool) T { + l.parent.appendItem(value.BoolValue(v)) return l.parent } -func (l *listItem) Uint64(v uint64) *list { - l.parent.values = append(l.parent.values, value.Uint64Value(v)) +func (l listItem[T]) Uint64(v uint64) T { + l.parent.appendItem(value.Uint64Value(v)) return l.parent } -func (l *listItem) Int64(v int64) *list { - l.parent.values = append(l.parent.values, value.Int64Value(v)) +func (l listItem[T]) Int64(v int64) T { + l.parent.appendItem(value.Int64Value(v)) return l.parent } -func (l *listItem) Uint32(v uint32) *list { - l.parent.values = append(l.parent.values, value.Uint32Value(v)) +func (l listItem[T]) Uint32(v uint32) T { + l.parent.appendItem(value.Uint32Value(v)) return l.parent } -func (l *listItem) Int32(v int32) *list { - l.parent.values = append(l.parent.values, value.Int32Value(v)) +func (l listItem[T]) Int32(v int32) T { + l.parent.appendItem(value.Int32Value(v)) return l.parent } -func (l *listItem) Uint16(v uint16) *list { - l.parent.values = append(l.parent.values, value.Uint16Value(v)) +func (l listItem[T]) Uint16(v uint16) T { + l.parent.appendItem(value.Uint16Value(v)) return l.parent } -func (l *listItem) Int16(v int16) *list { - l.parent.values = append(l.parent.values, value.Int16Value(v)) +func (l listItem[T]) Int16(v int16) T { + l.parent.appendItem(value.Int16Value(v)) return l.parent } -func (l *listItem) Uint8(v uint8) *list { - l.parent.values = append(l.parent.values, value.Uint8Value(v)) +func (l listItem[T]) Uint8(v uint8) T { + l.parent.appendItem(value.Uint8Value(v)) return l.parent } -func (l *listItem) Int8(v int8) *list { - l.parent.values = append(l.parent.values, value.Int8Value(v)) +func (l listItem[T]) Int8(v int8) T { + l.parent.appendItem(value.Int8Value(v)) return l.parent } -func (l *listItem) Float(v float32) *list { - l.parent.values = append(l.parent.values, value.FloatValue(v)) +func (l listItem[T]) Float(v float32) T { + l.parent.appendItem(value.FloatValue(v)) return l.parent } -func (l *listItem) Double(v float64) *list { - l.parent.values = append(l.parent.values, value.DoubleValue(v)) +func (l listItem[T]) Double(v float64) T { + l.parent.appendItem(value.DoubleValue(v)) return l.parent } -func (l *listItem) Decimal(v [16]byte, precision, scale uint32) *list { - l.parent.values = append(l.parent.values, value.DecimalValue(v, precision, scale)) +func (l listItem[T]) Decimal(v [16]byte, precision, scale uint32) T { + l.parent.appendItem(value.DecimalValue(v, precision, scale)) return l.parent } -func (l *listItem) Timestamp(v time.Time) *list { - l.parent.values = append(l.parent.values, value.TimestampValueFromTime(v)) +func (l listItem[T]) Timestamp(v time.Time) T { + l.parent.appendItem(value.TimestampValueFromTime(v)) return l.parent } -func (l *listItem) Date(v time.Time) *list { - l.parent.values = append(l.parent.values, value.DateValueFromTime(v)) +func (l listItem[T]) Date(v time.Time) T { + l.parent.appendItem(value.DateValueFromTime(v)) return l.parent } -func (l *listItem) Datetime(v time.Time) *list { - l.parent.values = append(l.parent.values, value.DatetimeValueFromTime(v)) +func (l listItem[T]) Datetime(v time.Time) T { + l.parent.appendItem(value.DatetimeValueFromTime(v)) return l.parent } -func (l *listItem) Interval(v time.Duration) *list { - l.parent.values = append(l.parent.values, value.IntervalValueFromDuration(v)) +func (l listItem[T]) Interval(v time.Duration) T { + l.parent.appendItem(value.IntervalValueFromDuration(v)) return l.parent } -func (l *listItem) JSON(v string) *list { - l.parent.values = append(l.parent.values, value.JSONValue(v)) +func (l listItem[T]) JSON(v string) T { + l.parent.appendItem(value.JSONValue(v)) return l.parent } -func (l *listItem) JSONDocument(v string) *list { - l.parent.values = append(l.parent.values, value.JSONDocumentValue(v)) +func (l listItem[T]) JSONDocument(v string) T { + l.parent.appendItem(value.JSONDocumentValue(v)) return l.parent } -func (l *listItem) YSON(v []byte) *list { - l.parent.values = append(l.parent.values, value.YSONValue(v)) +func (l listItem[T]) YSON(v []byte) T { + l.parent.appendItem(value.YSONValue(v)) return l.parent } -func (l *listItem) UUID(v [16]byte) *list { - l.parent.values = append(l.parent.values, value.UUIDValue(v)) +func (l listItem[T]) UUID(v [16]byte) T { + l.parent.appendItem(value.UUIDValue(v)) return l.parent } diff --git a/internal/params/list_test.go b/internal/params/list_test.go index 3941a80c4..f1ffec097 100644 --- a/internal/params/list_test.go +++ b/internal/params/list_test.go @@ -46,6 +46,44 @@ func TestList(t *testing.T) { }, }, }, + { + name: xtest.CurrentFileLine(), + builder: Builder{}.Param("$x").BeginList().BeginList().BeginList().Add().Uint64(123).EndList().EndList().EndList(), + params: map[string]*Ydb.TypedValue{ + "$x": { + Type: &Ydb.Type{ + Type: &Ydb.Type_ListType{ + ListType: &Ydb.ListType{ + Item: &Ydb.Type{ + Type: &Ydb.Type_ListType{ + ListType: &Ydb.ListType{ + Item: &Ydb.Type{ + Type: &Ydb.Type_TypeId{ + TypeId: Ydb.Type_UINT64, + }, + }, + }, + }, + }, + }, + }, + }, + Value: &Ydb.Value{ + Items: []*Ydb.Value{ + { + Items: []*Ydb.Value{ + { + Value: &Ydb.Value_Uint64Value{ + Uint64Value: 123, + }, + }, + }, + }, + }, + }, + }, + }, + }, { name: xtest.CurrentFileLine(), builder: Builder{}.Param("$x").BeginList().Add().Int64(123).EndList(), diff --git a/internal/params/parameters.go b/internal/params/parameters.go index c96506048..66f847cca 100644 --- a/internal/params/parameters.go +++ b/internal/params/parameters.go @@ -102,8 +102,8 @@ func (p *Parameter) BeginOptional() *optional { } } -func (p *Parameter) BeginList() *list { - return &list{ +func (p *Parameter) BeginList() *list[Builder] { + return &list[Builder]{ parent: p.parent, name: p.name, }