github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/example_test.go (about) 1 package ydb_test 2 3 import ( 4 "context" 5 "database/sql" 6 "fmt" 7 "io" 8 "log" 9 "time" 10 11 "google.golang.org/grpc" 12 "google.golang.org/grpc/encoding/gzip" 13 14 "github.com/ydb-platform/ydb-go-sdk/v3" 15 "github.com/ydb-platform/ydb-go-sdk/v3/balancers" 16 "github.com/ydb-platform/ydb-go-sdk/v3/config" 17 "github.com/ydb-platform/ydb-go-sdk/v3/retry" 18 "github.com/ydb-platform/ydb-go-sdk/v3/table" 19 "github.com/ydb-platform/ydb-go-sdk/v3/table/result/named" 20 "github.com/ydb-platform/ydb-go-sdk/v3/table/types" 21 "github.com/ydb-platform/ydb-go-sdk/v3/topic/topicoptions" 22 ) 23 24 //nolint:testableexamples, nonamedreturns 25 func Example_table() { 26 ctx := context.TODO() 27 db, err := ydb.Open(ctx, "grpc://localhost:2136/local") 28 if err != nil { 29 log.Fatal(err) 30 } 31 defer db.Close(ctx) // cleanup resources 32 var ( 33 query = `SELECT 42 as id, "my string" as myStr` 34 id int32 // required value 35 myStr string // optional value 36 ) 37 err = db.Table().Do( // Do retry operation on errors with best effort 38 ctx, // context manage exiting from Do 39 func(ctx context.Context, s table.Session) (err error) { // retry operation 40 _, res, err := s.Execute(ctx, table.DefaultTxControl(), query, nil) 41 if err != nil { 42 return err // for auto-retry with driver 43 } 44 defer res.Close() // cleanup resources 45 if err = res.NextResultSetErr(ctx); err != nil { // check single result set and switch to it 46 return err // for auto-retry with driver 47 } 48 for res.NextRow() { // iterate over rows 49 err = res.ScanNamed( 50 named.Required("id", &id), 51 named.OptionalWithDefault("myStr", &myStr), 52 ) 53 if err != nil { 54 return err // generally scan error not retryable, return it for driver check error 55 } 56 log.Printf("id=%v, myStr='%s'\n", id, myStr) 57 } 58 59 return res.Err() // return finally result error for auto-retry with driver 60 }, 61 table.WithIdempotent(), 62 ) 63 if err != nil { 64 log.Printf("unexpected error: %v", err) 65 } 66 } 67 68 //nolint:testableexamples 69 func Example_databaseSQL() { 70 db, err := sql.Open("ydb", "grpc://localhost:2136/local") 71 if err != nil { 72 log.Fatal(err) 73 } 74 defer func() { _ = db.Close() }() // cleanup resources 75 76 db.SetMaxOpenConns(100) 77 db.SetMaxIdleConns(100) 78 db.SetConnMaxIdleTime(time.Second) // workaround for background keep-aliving of YDB sessions 79 80 var ( 81 id int32 // required value 82 myStr string // optional value 83 ) 84 // retry transaction 85 err = retry.DoTx(context.TODO(), db, func(ctx context.Context, tx *sql.Tx) error { 86 row := tx.QueryRowContext(ctx, `SELECT 42 as id, "my string" as myStr`) 87 if err = row.Scan(&id, &myStr); err != nil { 88 return err 89 } 90 log.Printf("id=%v, myStr='%s'\n", id, myStr) 91 92 return nil 93 }, retry.WithIdempotent(true)) 94 if err != nil { 95 log.Printf("query failed: %v", err) 96 } 97 } 98 99 //nolint:testableexamples 100 func Example_databaseSQLBindNumericArgs() { 101 db, err := sql.Open("ydb", 102 "grpc://localhost:2136/local?go_query_bind=declare,numeric", 103 ) 104 if err != nil { 105 log.Fatal(err) 106 } 107 defer func() { _ = db.Close() }() // cleanup resources 108 109 var ( 110 id int32 // required value 111 myStr string // optional value 112 ) 113 114 // numeric args 115 row := db.QueryRowContext(context.TODO(), "SELECT $2, $1", 42, "my string") 116 if err = row.Scan(&myStr, &id); err != nil { 117 log.Printf("query failed: %v", err) 118 } else { 119 log.Printf("id=%v, myStr='%s'\n", id, myStr) 120 } 121 } 122 123 //nolint:testableexamples 124 func Example_databaseSQLBindNumericArgsOverConnector() { 125 var ( 126 ctx = context.TODO() 127 nativeDriver = ydb.MustOpen(ctx, "grpc://localhost:2136/local") 128 db = sql.OpenDB( 129 ydb.MustConnector(nativeDriver, 130 ydb.WithAutoDeclare(), 131 ydb.WithNumericArgs(), 132 ), 133 ) 134 ) 135 defer nativeDriver.Close(ctx) // cleanup resources 136 defer db.Close() 137 138 // numeric args 139 row := db.QueryRowContext(context.TODO(), 140 "SELECT $2, $1", 141 42, "my string", 142 ) 143 144 var ( 145 id int32 // required value 146 myStr string // optional value 147 ) 148 if err := row.Scan(&myStr, &id); err != nil { 149 log.Printf("query failed: %v", err) 150 } else { 151 log.Printf("id=%v, myStr='%s'\n", id, myStr) 152 } 153 } 154 155 //nolint:testableexamples 156 func Example_databaseSQLBindPositionalArgs() { 157 db, err := sql.Open("ydb", 158 "grpc://localhost:2136/local?go_query_bind=declare,positional", 159 ) 160 if err != nil { 161 log.Fatal(err) 162 } 163 defer func() { _ = db.Close() }() // cleanup resources 164 165 var ( 166 id int32 // required value 167 myStr string // optional value 168 ) 169 170 // positional args 171 row := db.QueryRowContext(context.TODO(), "SELECT ?, ?", 42, "my string") 172 if err = row.Scan(&id, &myStr); err != nil { 173 log.Printf("query failed: %v", err) 174 } else { 175 log.Printf("id=%v, myStr='%s'\n", id, myStr) 176 } 177 } 178 179 //nolint:testableexamples 180 func Example_databaseSQLBindPositionalArgsOverConnector() { 181 var ( 182 ctx = context.TODO() 183 nativeDriver = ydb.MustOpen(ctx, "grpc://localhost:2136/local") 184 db = sql.OpenDB( 185 ydb.MustConnector(nativeDriver, 186 ydb.WithAutoDeclare(), 187 ydb.WithNumericArgs(), 188 ), 189 ) 190 ) 191 defer nativeDriver.Close(ctx) // cleanup resources 192 defer db.Close() 193 194 // positional args 195 row := db.QueryRowContext(context.TODO(), "SELECT ?, ?", 42, "my string") 196 197 var ( 198 id int32 // required value 199 myStr string // optional value 200 ) 201 if err := row.Scan(&id, &myStr); err != nil { 202 log.Printf("query failed: %v", err) 203 } else { 204 log.Printf("id=%v, myStr='%s'\n", id, myStr) 205 } 206 } 207 208 //nolint:testableexamples 209 func Example_databaseSQLBindTablePathPrefix() { 210 db, err := sql.Open("ydb", 211 "grpc://localhost:2136/local?go_query_bind=table_path_prefix(/local/path/to/tables)", 212 ) 213 if err != nil { 214 log.Fatal(err) 215 } 216 defer func() { _ = db.Close() }() // cleanup resources 217 218 var ( 219 id int32 // required value 220 title string // optional value 221 ) 222 223 // full table path is "/local/path/to/tables/series" 224 row := db.QueryRowContext(context.TODO(), "SELECT id, title FROM series") 225 if err = row.Scan(&id, &title); err != nil { 226 log.Printf("query failed: %v", err) 227 } else { 228 log.Printf("id=%v, title='%s'\n", id, title) 229 } 230 } 231 232 //nolint:testableexamples 233 func Example_databaseSQLBindTablePathPrefixOverConnector() { 234 var ( 235 ctx = context.TODO() 236 nativeDriver = ydb.MustOpen(ctx, "grpc://localhost:2136/local") 237 db = sql.OpenDB(ydb.MustConnector(nativeDriver, 238 ydb.WithTablePathPrefix("/local/path/to/my/folder"), 239 )) 240 ) 241 242 // full table path is "/local/path/to/tables/series" 243 row := db.QueryRowContext(context.TODO(), "SELECT id, title FROM series") 244 245 var ( 246 id int32 // required value 247 title string // optional value 248 ) 249 if err := row.Scan(&id, &title); err != nil { 250 log.Printf("query failed: %v", err) 251 } else { 252 log.Printf("id=%v, title='%s'\n", id, title) 253 } 254 } 255 256 //nolint:testableexamples 257 func Example_databaseSQLBindAutoDeclare() { 258 db, err := sql.Open("ydb", 259 "grpc://localhost:2136/local?go_query_bind=declare", 260 ) 261 if err != nil { 262 log.Fatal(err) 263 } 264 defer func() { _ = db.Close() }() // cleanup resources 265 266 var ( 267 id int32 // required value 268 title string // optional value 269 ) 270 271 row := db.QueryRowContext(context.TODO(), "SELECT $id, $title", 272 table.ValueParam("$id", types.Uint64Value(42)), 273 table.ValueParam("$title", types.TextValue("title")), 274 ) 275 if err = row.Scan(&id, &title); err != nil { 276 log.Printf("query failed: %v", err) 277 } else { 278 log.Printf("id=%v, title='%s'\n", id, title) 279 } 280 } 281 282 //nolint:testableexamples 283 func Example_databaseSQLBindAutoDeclareOverConnector() { 284 var ( 285 ctx = context.TODO() 286 nativeDriver = ydb.MustOpen(ctx, "grpc://localhost:2136/local") 287 db = sql.OpenDB(ydb.MustConnector(nativeDriver, 288 ydb.WithAutoDeclare(), 289 )) 290 ) 291 292 row := db.QueryRowContext(context.TODO(), "SELECT $id, $title", 293 table.ValueParam("$id", types.Uint64Value(42)), 294 table.ValueParam("$title", types.TextValue("title")), 295 ) 296 297 var ( 298 id int32 // required value 299 title string // optional value 300 ) 301 if err := row.Scan(&id, &title); err != nil { 302 log.Printf("query failed: %v", err) 303 } else { 304 log.Printf("id=%v, title='%s'\n", id, title) 305 } 306 } 307 308 //nolint:testableexamples 309 func Example_topic() { 310 ctx := context.TODO() 311 db, err := ydb.Open(ctx, "grpc://localhost:2136/local") 312 if err != nil { 313 fmt.Printf("failed connect: %v", err) 314 315 return 316 } 317 defer db.Close(ctx) // cleanup resources 318 319 reader, err := db.Topic().StartReader("consumer", topicoptions.ReadTopic("/topic/path")) 320 if err != nil { 321 fmt.Printf("failed start reader: %v", err) 322 323 return 324 } 325 326 for { 327 mess, err := reader.ReadMessage(ctx) 328 if err != nil { 329 fmt.Printf("failed start reader: %v", err) 330 331 return 332 } 333 334 content, err := io.ReadAll(mess) 335 if err != nil { 336 fmt.Printf("failed start reader: %v", err) 337 338 return 339 } 340 fmt.Println(string(content)) 341 } 342 } 343 344 //nolint:testableexamples 345 func Example_scripting() { 346 ctx := context.TODO() 347 db, err := ydb.Open(ctx, "grpc://localhost:2136/local") 348 if err != nil { 349 fmt.Printf("failed to connect: %v", err) 350 351 return 352 } 353 defer db.Close(ctx) // cleanup resources 354 if err = retry.Retry(ctx, func(ctx context.Context) (err error) { //nolint:nonamedreturns 355 res, err := db.Scripting().Execute( 356 ctx, 357 "SELECT 1+1", 358 table.NewQueryParameters(), 359 ) 360 if err != nil { 361 return err 362 } 363 defer res.Close() // cleanup resources 364 if !res.NextResultSet(ctx) { 365 return retry.RetryableError( 366 fmt.Errorf("no result sets"), //nolint:goerr113 367 retry.WithBackoff(retry.TypeNoBackoff), 368 ) 369 } 370 if !res.NextRow() { 371 return retry.RetryableError( 372 fmt.Errorf("no rows"), //nolint:goerr113 373 retry.WithBackoff(retry.TypeSlowBackoff), 374 ) 375 } 376 var sum int32 377 if err = res.Scan(&sum); err != nil { 378 return fmt.Errorf("scan failed: %w", err) 379 } 380 if sum != 2 { 381 return fmt.Errorf("unexpected sum: %v", sum) //nolint:goerr113 382 } 383 384 return res.Err() 385 }, retry.WithIdempotent(true)); err != nil { 386 fmt.Printf("Execute failed: %v", err) 387 } 388 } 389 390 //nolint:testableexamples 391 func Example_discovery() { 392 ctx := context.TODO() 393 db, err := ydb.Open(ctx, "grpc://localhost:2136/local") 394 if err != nil { 395 fmt.Printf("failed to connect: %v", err) 396 397 return 398 } 399 defer db.Close(ctx) // cleanup resources 400 endpoints, err := db.Discovery().Discover(ctx) 401 if err != nil { 402 fmt.Printf("discover failed: %v", err) 403 404 return 405 } 406 fmt.Printf("%s endpoints:\n", db.Name()) 407 for i, e := range endpoints { 408 fmt.Printf("%d) %s\n", i, e.String()) 409 } 410 } 411 412 //nolint:testableexamples 413 func Example_enableGzipCompressionForAllRequests() { 414 ctx := context.TODO() 415 db, err := ydb.Open( 416 ctx, 417 "grpc://localhost:2135/local", 418 ydb.WithAnonymousCredentials(), 419 ydb.With(config.WithGrpcOptions( 420 grpc.WithDefaultCallOptions( 421 grpc.UseCompressor(gzip.Name), 422 ), 423 )), 424 ) 425 if err != nil { 426 fmt.Printf("Driver failed: %v", err) 427 } 428 defer db.Close(ctx) // cleanup resources 429 fmt.Printf("connected to %s, database '%s'", db.Endpoint(), db.Name()) 430 } 431 432 //nolint:testableexamples 433 func ExampleOpen() { 434 ctx := context.TODO() 435 db, err := ydb.Open(ctx, "grpc://localhost:2135/local") 436 if err != nil { 437 fmt.Printf("Driver failed: %v", err) 438 } 439 defer db.Close(ctx) // cleanup resources 440 fmt.Printf("connected to %s, database '%s'", db.Endpoint(), db.Name()) 441 } 442 443 //nolint:testableexamples 444 func ExampleOpen_advanced() { 445 ctx := context.TODO() 446 db, err := ydb.Open( 447 ctx, 448 "grpc://localhost:2135/local", 449 ydb.WithAnonymousCredentials(), 450 ydb.WithBalancer( 451 balancers.PreferLocationsWithFallback( 452 balancers.RandomChoice(), "a", "b", 453 ), 454 ), 455 ydb.WithSessionPoolSizeLimit(100), 456 ) 457 if err != nil { 458 fmt.Printf("Driver failed: %v", err) 459 } 460 defer db.Close(ctx) // cleanup resources 461 fmt.Printf("connected to %s, database '%s'", db.Endpoint(), db.Name()) 462 }