Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit fe804c6

Browse files
committedDec 27, 2024·
support custom types in query result scanning
1 parent 4068af9 commit fe804c6

File tree

4 files changed

+42
-2
lines changed

4 files changed

+42
-2
lines changed
 

‎CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
* Added support of custom types to row.ScanStruc
2+
13
## v3.95.5
24
* Fixed goroutine leak on failed execute call in query client
35

‎internal/value/cast.go

+8
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,13 @@ func CastTo(v Value, dst interface{}) error {
1010
return nil
1111
}
1212

13+
if scanner, has := dst.(Scanner); has {
14+
return scanner.UnmarshalYDBValue(v)
15+
}
16+
1317
return v.castTo(dst)
1418
}
19+
20+
type Scanner interface {
21+
UnmarshalYDBValue(value Value) error
22+
}

‎internal/value/cast_test.go

+15
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ func loadLocation(t *testing.T, name string) *time.Location {
3232
return loc
3333
}
3434

35+
type testStringValueScanner struct {
36+
field string
37+
}
38+
39+
func (s *testStringValueScanner) UnmarshalYDBValue(v Value) error {
40+
return CastTo(v, &s.field)
41+
}
42+
3543
func TestCastTo(t *testing.T) {
3644
testsCases := []struct {
3745
name string
@@ -428,6 +436,13 @@ func TestCastTo(t *testing.T) {
428436
exp: DateValueFromTime(time.Date(2024, 1, 2, 0, 0, 0, 0, time.UTC)),
429437
err: nil,
430438
},
439+
{
440+
name: xtest.CurrentFileLine(),
441+
value: TextValue("text-string"),
442+
dst: ptr[testStringValueScanner](),
443+
exp: testStringValueScanner{field: "text-string"},
444+
err: nil,
445+
},
431446
}
432447
for _, tt := range testsCases {
433448
t.Run(tt.name, func(t *testing.T) {

‎tests/integration/query_range_test.go

+17-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,17 @@ import (
1717
"github.com/ydb-platform/ydb-go-sdk/v3/internal/value"
1818
"github.com/ydb-platform/ydb-go-sdk/v3/internal/xtest"
1919
"github.com/ydb-platform/ydb-go-sdk/v3/query"
20+
"github.com/ydb-platform/ydb-go-sdk/v3/table/types"
2021
)
2122

23+
type testStringValueScanner struct {
24+
field string
25+
}
26+
27+
func (v *testStringValueScanner) UnmarshalYDBValue(value types.Value) error {
28+
return types.CastTo(value, &v.field)
29+
}
30+
2231
func TestQueryRange(t *testing.T) {
2332
ctx, cancel := context.WithCancel(xtest.Context(t))
2433
defer cancel()
@@ -84,19 +93,22 @@ func TestQueryRange(t *testing.T) {
8493
p1 string
8594
p2 uint64
8695
p3 time.Duration
96+
p4 testStringValueScanner
8797
)
8898
err := db.Query().Do(ctx, func(ctx context.Context, s query.Session) error {
8999
r, err := s.Query(ctx, `
90100
DECLARE $p1 AS Text;
91101
DECLARE $p2 AS Uint64;
92102
DECLARE $p3 AS Interval;
93-
SELECT $p1, $p2, $p3;
103+
DECLARE $p4 AS Text;
104+
SELECT $p1, $p2, $p3, $p4;
94105
`,
95106
query.WithParameters(
96107
ydb.ParamsBuilder().
97108
Param("$p1").Text("test").
98109
Param("$p2").Uint64(100500000000).
99110
Param("$p3").Interval(time.Duration(100500000000)).
111+
Param("$p4").Text("test2").
100112
Build(),
101113
),
102114
query.WithSyntax(query.SyntaxYQL),
@@ -112,7 +124,7 @@ func TestQueryRange(t *testing.T) {
112124
if err != nil {
113125
return err
114126
}
115-
err = row.Scan(&p1, &p2, &p3)
127+
err = row.Scan(&p1, &p2, &p3, &p4)
116128
if err != nil {
117129
return err
118130
}
@@ -126,6 +138,9 @@ func TestQueryRange(t *testing.T) {
126138
if p3 != time.Duration(100500000000) {
127139
return fmt.Errorf("unexpected p3 value: %v", p3)
128140
}
141+
if p4.field != "test2" {
142+
return fmt.Errorf("unexpected p4 value: %v", p4)
143+
}
129144
}
130145
}
131146
return nil

0 commit comments

Comments
 (0)
Please sign in to comment.