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  }