github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/tests/integration/table_containers_test.go (about) 1 //go:build integration 2 // +build integration 3 4 package integration 5 6 import ( 7 "context" 8 "os" 9 "testing" 10 11 "github.com/stretchr/testify/require" 12 13 "github.com/ydb-platform/ydb-go-sdk/v3" 14 "github.com/ydb-platform/ydb-go-sdk/v3/table" 15 "github.com/ydb-platform/ydb-go-sdk/v3/table/types" 16 ) 17 18 // Containers example demonstrates how to work with YDB container values such as `List`, `Tuple`, `Dict`, `Struct` and `Variant` 19 func TestContainers(t *testing.T) { 20 ctx, cancel := context.WithCancel(context.Background()) 21 defer cancel() 22 23 db, err := ydb.Open(ctx, 24 os.Getenv("YDB_CONNECTION_STRING"), 25 ydb.WithAccessTokenCredentials(os.Getenv("YDB_ACCESS_TOKEN_CREDENTIALS")), 26 ) 27 require.NoError(t, err) 28 err = db.Table().DoTx(ctx, func(ctx context.Context, tx table.TransactionActor) (err error) { 29 res, err := tx.Execute(ctx, ` 30 SELECT 31 AsList("foo", "bar", "baz"); 32 SELECT 33 AsTuple(42, "foo", AsList(41, 42, 43)); 34 SELECT 35 AsDict( 36 AsTuple("foo", 10), 37 AsTuple("bar", 20), 38 AsTuple("baz", 30), 39 ); 40 SELECT 41 AsStruct( 42 41 AS foo, 43 42 AS bar, 44 43 AS baz, 45 ); 46 47 $struct = AsStruct( 48 Uint32("0") as foo, 49 UTF8("x") as bar, 50 Int64("0") as baz, 51 ); 52 $variantStructType = VariantType(TypeOf($struct)); 53 SELECT Variant(42, "baz", $variantStructType); 54 55 $tuple = AsTuple( 56 Uint32("0"), 57 UTF8("x"), 58 Int64("0"), 59 ); 60 $variantTupleType = VariantType(TypeOf($tuple)); 61 SELECT Variant(42, "2", $variantTupleType); 62 `, nil) 63 if err != nil { 64 return err 65 } 66 defer func() { 67 _ = res.Close() 68 }() 69 70 parsers := [...]func() error{ 71 func() error { 72 return res.Scan(&testContainersExampleList{test: t}) 73 }, 74 func() error { 75 return res.Scan(&testContainersExampleTuple{test: t}) 76 }, 77 func() error { 78 return res.Scan(&testContainersExampleDict{test: t}) 79 }, 80 func() error { 81 return res.Scan(&testContainersExampleStruct{test: t}) 82 }, 83 func() error { 84 return res.Scan(&testContainersVariantStruct{test: t}) 85 }, 86 func() error { 87 return res.Scan(&testContainersVariantTuple{test: t}) 88 }, 89 } 90 91 for set := 0; res.NextResultSet(ctx); set++ { 92 res.NextRow() 93 err = parsers[set]() 94 if err != nil { 95 return err 96 } 97 } 98 return res.Err() 99 }, table.WithTxSettings(table.TxSettings(table.WithSnapshotReadOnly())), table.WithIdempotent()) 100 require.NoError(t, err) 101 } 102 103 type testContainersExampleStruct struct { 104 test testing.TB 105 } 106 107 func (s *testContainersExampleStruct) UnmarshalYDB(res types.RawValue) error { 108 s.test.Logf("T: %s", res.Type()) 109 for i, n := 0, res.StructIn(); i < n; i++ { 110 name := res.StructField(i) 111 val := res.Int32() 112 s.test.Logf("(struct): %s: %d", name, val) 113 } 114 res.StructOut() 115 return res.Err() 116 } 117 118 type testContainersExampleList struct { 119 test testing.TB 120 } 121 122 func (c *testContainersExampleList) UnmarshalYDB(res types.RawValue) error { 123 c.test.Logf("T: %s", res.Type()) 124 for i, n := 0, res.ListIn(); i < n; i++ { 125 res.ListItem(i) 126 c.test.Logf("(list) %q: %s", res.Path(), res.String()) 127 } 128 res.ListOut() 129 return res.Err() 130 } 131 132 type testContainersExampleTuple struct { 133 test testing.TB 134 } 135 136 func (c *testContainersExampleTuple) UnmarshalYDB(res types.RawValue) error { 137 c.test.Logf("T: %s", res.Type()) 138 for i, n := 0, res.TupleIn(); i < n; i++ { 139 res.TupleItem(i) 140 switch i { 141 case 0: 142 c.test.Logf("(tuple) %q: %d", res.Path(), res.Int32()) 143 case 1: 144 c.test.Logf("(tuple) %q: %s", res.Path(), res.String()) 145 case 2: 146 n := res.ListIn() 147 for j := 0; j < n; j++ { 148 res.ListItem(j) 149 c.test.Logf("(tuple) %q: %d", res.Path(), res.Int32()) 150 } 151 res.ListOut() 152 } 153 } 154 res.TupleOut() 155 return res.Err() 156 } 157 158 type testContainersExampleDict struct { 159 test testing.TB 160 } 161 162 func (c *testContainersExampleDict) UnmarshalYDB(res types.RawValue) error { 163 c.test.Logf("T: %s", res.Type()) 164 for i, n := 0, res.DictIn(); i < n; i++ { 165 res.DictKey(i) 166 key := res.String() 167 168 res.DictPayload(i) 169 val := res.Int32() 170 171 c.test.Logf("(dict) %q: %s: %d", res.Path(), key, val) 172 } 173 res.DictOut() 174 return res.Err() 175 } 176 177 type testContainersVariantStruct struct { 178 test testing.TB 179 } 180 181 func (c *testContainersVariantStruct) UnmarshalYDB(res types.RawValue) error { 182 c.test.Logf("T: %s", res.Type()) 183 name, index := res.Variant() 184 var x interface{} 185 switch name { 186 case "foo": 187 x = res.Uint32() 188 case "bar": 189 x = res.UTF8() 190 case "baz": 191 x = res.Int64() 192 } 193 c.test.Logf( 194 "(struct variant): %s %s %q %d = %v", 195 res.Path(), res.Type(), name, index, x, 196 ) 197 return res.Err() 198 } 199 200 type testContainersVariantTuple struct { 201 test testing.TB 202 } 203 204 func (c *testContainersVariantTuple) UnmarshalYDB(res types.RawValue) error { 205 c.test.Logf("T: %s", res.Type()) 206 name, index := res.Variant() 207 var x interface{} 208 switch index { 209 case 0: 210 x = res.Uint32() 211 case 1: 212 x = res.UTF8() 213 case 2: 214 x = res.Int64() 215 } 216 c.test.Logf( 217 "(tuple variant): %s %s %q %d = %v", 218 res.Path(), res.Type(), name, index, x, 219 ) 220 return res.Err() 221 }