github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/tests/integration/query_execute_test.go (about) 1 //go:build integration 2 // +build integration 3 4 package integration 5 6 import ( 7 "context" 8 "fmt" 9 "os" 10 "testing" 11 "time" 12 13 "github.com/stretchr/testify/require" 14 15 "github.com/ydb-platform/ydb-go-sdk/v3" 16 "github.com/ydb-platform/ydb-go-sdk/v3/internal/version" 17 "github.com/ydb-platform/ydb-go-sdk/v3/query" 18 ) 19 20 func TestQueryExecute(t *testing.T) { 21 if version.Lt(os.Getenv("YDB_VERSION"), "24.1") { 22 t.Skip("query service not allowed in YDB version '" + os.Getenv("YDB_VERSION") + "'") 23 } 24 25 ctx, cancel := context.WithCancel(context.Background()) 26 defer cancel() 27 28 db, err := ydb.Open(ctx, 29 os.Getenv("YDB_CONNECTION_STRING"), 30 ydb.WithAccessTokenCredentials(os.Getenv("YDB_ACCESS_TOKEN_CREDENTIALS")), 31 ) 32 require.NoError(t, err) 33 t.Run("Scan", func(t *testing.T) { 34 var ( 35 p1 string 36 p2 uint64 37 p3 time.Duration 38 ) 39 err = db.Query().Do(ctx, func(ctx context.Context, s query.Session) (err error) { 40 _, res, err := s.Execute(ctx, ` 41 DECLARE $p1 AS Text; 42 DECLARE $p2 AS Uint64; 43 DECLARE $p3 AS Interval; 44 SELECT $p1, $p2, $p3; 45 `, 46 query.WithParameters( 47 ydb.ParamsBuilder(). 48 Param("$p1").Text("test"). 49 Param("$p2").Uint64(100500000000). 50 Param("$p3").Interval(time.Duration(100500000000)). 51 Build(), 52 ), 53 query.WithSyntax(query.SyntaxYQL), 54 ) 55 if err != nil { 56 return err 57 } 58 rs, err := res.NextResultSet(ctx) 59 if err != nil { 60 return err 61 } 62 row, err := rs.NextRow(ctx) 63 if err != nil { 64 return err 65 } 66 err = row.Scan(&p1, &p2, &p3) 67 if err != nil { 68 return err 69 } 70 return res.Err() 71 }, query.WithIdempotent()) 72 require.NoError(t, err) 73 require.EqualValues(t, "test", p1) 74 require.EqualValues(t, 100500000000, p2) 75 require.EqualValues(t, time.Duration(100500000000), p3) 76 }) 77 t.Run("ScanNamed", func(t *testing.T) { 78 var ( 79 p1 string 80 p2 uint64 81 p3 time.Duration 82 ) 83 err = db.Query().Do(ctx, func(ctx context.Context, s query.Session) (err error) { 84 _, res, err := s.Execute(ctx, ` 85 DECLARE $p1 AS Text; 86 DECLARE $p2 AS Uint64; 87 DECLARE $p3 AS Interval; 88 SELECT $p1 AS p1, $p2 AS p2, $p3 AS p3; 89 `, 90 query.WithParameters( 91 ydb.ParamsBuilder(). 92 Param("$p1").Text("test"). 93 Param("$p2").Uint64(100500000000). 94 Param("$p3").Interval(time.Duration(100500000000)). 95 Build(), 96 ), 97 query.WithSyntax(query.SyntaxYQL), 98 ) 99 if err != nil { 100 return err 101 } 102 rs, err := res.NextResultSet(ctx) 103 if err != nil { 104 return err 105 } 106 row, err := rs.NextRow(ctx) 107 if err != nil { 108 return err 109 } 110 err = row.ScanNamed( 111 query.Named("p1", &p1), 112 query.Named("p2", &p2), 113 query.Named("p3", &p3), 114 ) 115 if err != nil { 116 return err 117 } 118 return res.Err() 119 }, query.WithIdempotent()) 120 require.NoError(t, err) 121 require.EqualValues(t, "test", p1) 122 require.EqualValues(t, 100500000000, p2) 123 require.EqualValues(t, time.Duration(100500000000), p3) 124 }) 125 t.Run("ScanStruct", func(t *testing.T) { 126 var data struct { 127 P1 *string `sql:"p1"` 128 P2 uint64 `sql:"p2"` 129 P3 time.Duration `sql:"p3"` 130 P4 *string `sql:"p4"` 131 } 132 err = db.Query().Do(ctx, func(ctx context.Context, s query.Session) (err error) { 133 _, res, err := s.Execute(ctx, ` 134 DECLARE $p1 AS Text; 135 DECLARE $p2 AS Uint64; 136 DECLARE $p3 AS Interval; 137 SELECT CAST($p1 AS Optional<Text>) AS p1, $p2 AS p2, $p3 AS p3, CAST(NULL AS Optional<Text>) AS p4; 138 `, 139 query.WithParameters( 140 ydb.ParamsBuilder(). 141 Param("$p1").Text("test"). 142 Param("$p2").Uint64(100500000000). 143 Param("$p3").Interval(time.Duration(100500000000)). 144 Build(), 145 ), 146 query.WithSyntax(query.SyntaxYQL), 147 ) 148 if err != nil { 149 return err 150 } 151 rs, err := res.NextResultSet(ctx) 152 if err != nil { 153 return err 154 } 155 row, err := rs.NextRow(ctx) 156 if err != nil { 157 return err 158 } 159 err = row.ScanStruct(&data) 160 if err != nil { 161 return err 162 } 163 return res.Err() 164 }, query.WithIdempotent()) 165 require.NoError(t, err) 166 require.NotNil(t, data.P1) 167 require.EqualValues(t, "test", *data.P1) 168 require.EqualValues(t, 100500000000, data.P2) 169 require.EqualValues(t, time.Duration(100500000000), data.P3) 170 require.Nil(t, data.P4) 171 }) 172 t.Run("Transaction", func(t *testing.T) { 173 t.Run("Explicit", func(t *testing.T) { 174 err = db.Query().Do(ctx, func(ctx context.Context, s query.Session) (err error) { 175 tx, err := s.Begin(ctx, query.TxSettings(query.WithSerializableReadWrite())) 176 if err != nil { 177 return err 178 } 179 res, err := tx.Execute(ctx, `SELECT 1`) 180 if err != nil { 181 return err 182 } 183 rs, err := res.NextResultSet(ctx) 184 if err != nil { 185 return err 186 } 187 row, err := rs.NextRow(ctx) 188 if err != nil { 189 return err 190 } 191 var v int32 192 err = row.Scan(&v) 193 if err != nil { 194 return err 195 } 196 if v != 1 { 197 return fmt.Errorf("unexpected value from database: %d", v) 198 } 199 if err = res.Err(); err != nil { 200 return err 201 } 202 return tx.CommitTx(ctx) 203 }, query.WithIdempotent()) 204 require.NoError(t, err) 205 }) 206 t.Run("Lazy", func(t *testing.T) { 207 err = db.Query().Do(ctx, func(ctx context.Context, s query.Session) (err error) { 208 tx, res, err := s.Execute(ctx, `SELECT 1`, 209 query.WithTxControl(query.TxControl(query.BeginTx(query.WithSerializableReadWrite()))), 210 ) 211 if err != nil { 212 return err 213 } 214 rs, err := res.NextResultSet(ctx) 215 if err != nil { 216 return err 217 } 218 row, err := rs.NextRow(ctx) 219 if err != nil { 220 return err 221 } 222 var v int32 223 err = row.Scan(&v) 224 if err != nil { 225 return err 226 } 227 if v != 1 { 228 return fmt.Errorf("unexpected value from database: %d", v) 229 } 230 if err = res.Err(); err != nil { 231 return err 232 } 233 res, err = tx.Execute(ctx, `SELECT 2`, query.WithCommit()) 234 if err != nil { 235 return err 236 } 237 rs, err = res.NextResultSet(ctx) 238 if err != nil { 239 return err 240 } 241 row, err = rs.NextRow(ctx) 242 if err != nil { 243 return err 244 } 245 err = row.Scan(&v) 246 if err != nil { 247 return err 248 } 249 if v != 2 { 250 return fmt.Errorf("unexpected value from database: %d", v) 251 } 252 return res.Err() 253 }, query.WithIdempotent()) 254 require.NoError(t, err) 255 }) 256 }) 257 }