Skip to content

Commit 132dfcc

Browse files
authored
Merge pull request #1091 from ydb-platform/scan-struct
ScanStruct implementation
2 parents e4db064 + d358ec7 commit 132dfcc

21 files changed

+1641
-687
lines changed

internal/query/errors.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ import (
77
var (
88
ErrNotImplemented = errors.New("not implemented yet")
99
errWrongNextResultSetIndex = errors.New("wrong result set index")
10-
errColumnNotFoundByName = errors.New("column not found by name")
1110
errInterruptedStream = errors.New("interrupted stream")
1211
errClosedResult = errors.New("result closed early")
1312
errWrongResultSetIndex = errors.New("critical violation of the logic - wrong result set index")
14-
errWrongArgumentsCount = errors.New("wrong arguments count")
1513
)

internal/query/row.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,24 @@ package query
33
import (
44
"github.com/ydb-platform/ydb-go-genproto/protos/Ydb"
55

6+
"github.com/ydb-platform/ydb-go-sdk/v3/internal/query/scanner"
67
"github.com/ydb-platform/ydb-go-sdk/v3/query"
78
)
89

910
var _ query.Row = (*row)(nil)
1011

1112
type row struct {
12-
scannerIndexed
13-
scannerNamed
14-
scannerStruct
13+
scanner.IndexedScanner
14+
scanner.NamedScanner
15+
scanner.StructScanner
1516
}
1617

1718
func newRow(columns []*Ydb.Column, v *Ydb.Value) (*row, error) {
18-
data := newScannerData(columns, v.GetItems())
19+
data := scanner.Data(columns, v.GetItems())
1920

2021
return &row{
21-
newScannerIndexed(data),
22-
newScannerNamed(data),
23-
newScannerStruct(data),
22+
scanner.Indexed(data),
23+
scanner.Named(data),
24+
scanner.Struct(data),
2425
}, nil
2526
}

internal/query/scanner/data.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package scanner
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/ydb-platform/ydb-go-genproto/protos/Ydb"
7+
8+
"github.com/ydb-platform/ydb-go-sdk/v3/internal/value"
9+
"github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors"
10+
)
11+
12+
type data struct {
13+
columns []*Ydb.Column
14+
values []*Ydb.Value
15+
}
16+
17+
func Data(columns []*Ydb.Column, values []*Ydb.Value) *data {
18+
return &data{
19+
columns: columns,
20+
values: values,
21+
}
22+
}
23+
24+
func (s data) seekByName(name string) (value.Value, error) {
25+
for i := range s.columns {
26+
if s.columns[i].GetName() == name {
27+
return value.FromYDB(s.columns[i].GetType(), s.values[i]), nil
28+
}
29+
}
30+
31+
return nil, xerrors.WithStackTrace(fmt.Errorf("'%s': %w", name, errColumnsNotFoundInRow))
32+
}
33+
34+
func (s data) seekByIndex(idx int) value.Value {
35+
return value.FromYDB(s.columns[idx].GetType(), s.values[idx])
36+
}

internal/query/scanner/errors.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package scanner
2+
3+
import (
4+
"errors"
5+
)
6+
7+
var (
8+
errColumnsNotFoundInRow = errors.New("some columns not found in row")
9+
errFieldsNotFoundInStruct = errors.New("some fields not found in struct")
10+
errIncompatibleColumnsAndDestinations = errors.New("incompatible columns and destinations")
11+
errDstTypeIsNotAPointer = errors.New("dst type is not a pointer")
12+
errDstTypeIsNotAPointerToStruct = errors.New("dst type is not a pointer to struct")
13+
)

internal/query/scanner/indexed.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package scanner
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/ydb-platform/ydb-go-sdk/v3/internal/value"
7+
"github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors"
8+
)
9+
10+
type IndexedScanner struct {
11+
data *data
12+
}
13+
14+
func Indexed(data *data) IndexedScanner {
15+
return IndexedScanner{
16+
data: data,
17+
}
18+
}
19+
20+
func (s IndexedScanner) Scan(dst ...interface{}) error {
21+
if len(dst) != len(s.data.columns) {
22+
return xerrors.WithStackTrace(
23+
fmt.Errorf("%w: %d != %d",
24+
errIncompatibleColumnsAndDestinations,
25+
len(dst), len(s.data.columns),
26+
),
27+
)
28+
}
29+
for i := range dst {
30+
v := s.data.seekByIndex(i)
31+
if err := value.CastTo(v, dst[i]); err != nil {
32+
return xerrors.WithStackTrace(err)
33+
}
34+
}
35+
36+
return nil
37+
}

0 commit comments

Comments
 (0)