github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/table/example_test.go (about) 1 package table_test 2 3 import ( 4 "context" 5 "fmt" 6 "path" 7 "time" 8 9 "google.golang.org/grpc" 10 "google.golang.org/grpc/encoding/gzip" 11 12 "github.com/ydb-platform/ydb-go-sdk/v3" 13 "github.com/ydb-platform/ydb-go-sdk/v3/retry" 14 "github.com/ydb-platform/ydb-go-sdk/v3/table" 15 "github.com/ydb-platform/ydb-go-sdk/v3/table/options" 16 "github.com/ydb-platform/ydb-go-sdk/v3/table/result/named" 17 "github.com/ydb-platform/ydb-go-sdk/v3/table/types" 18 ) 19 20 func Example_select() { 21 ctx := context.TODO() 22 db, err := ydb.Open(ctx, "grpc://localhost:2136/local") 23 if err != nil { 24 fmt.Printf("failed connect: %v", err) 25 26 return 27 } 28 defer db.Close(ctx) // cleanup resources 29 var ( 30 query = `SELECT 42 as id, "my string" as myStr` 31 id int32 // required value 32 myStr string // optional value 33 ) 34 err = db.Table().Do( // Do retry operation on errors with best effort 35 ctx, // context manage exiting from Do 36 func(ctx context.Context, s table.Session) (err error) { // retry operation 37 _, res, err := s.Execute(ctx, table.DefaultTxControl(), query, nil) 38 if err != nil { 39 return err // for auto-retry with driver 40 } 41 defer res.Close() // cleanup resources 42 if err = res.NextResultSetErr(ctx); err != nil { // check single result set and switch to it 43 return err // for auto-retry with driver 44 } 45 for res.NextRow() { // iterate over rows 46 err = res.ScanNamed( 47 named.Required("id", &id), 48 named.OptionalWithDefault("myStr", &myStr), 49 ) 50 if err != nil { 51 return err // generally scan error not retryable, return it for driver check error 52 } 53 fmt.Printf("id=%v, myStr='%s'\n", id, myStr) 54 } 55 56 return res.Err() // return finally result error for auto-retry with driver 57 }, 58 table.WithIdempotent(), 59 ) 60 if err != nil { 61 fmt.Printf("unexpected error: %v", err) 62 } 63 } 64 65 func Example_explainQuery() { 66 ctx := context.TODO() 67 db, err := ydb.Open(ctx, "grpc://localhost:2136/local") 68 if err != nil { 69 panic(err) 70 } 71 defer db.Close(ctx) // cleanup resources 72 var ( 73 plan string 74 ast string 75 ) 76 err = db.Table().Do( // Do retry operation on errors with best effort 77 ctx, // context manage exiting from Do 78 func(ctx context.Context, s table.Session) (err error) { // retry operation 79 explanation, err := s.Explain(ctx, ` 80 DECLARE $id AS Optional<Uint64>; 81 DECLARE $myStr AS Optional<Text>; 82 SELECT $id AS id, $myStr AS myStr; 83 `) 84 if err != nil { 85 return err // for auto-retry with driver 86 } 87 88 plan, ast = explanation.Plan, explanation.AST 89 90 return nil 91 }, 92 table.WithIdempotent(), 93 ) 94 if err != nil { 95 panic(err) 96 } 97 98 fmt.Printf("Plan: %s\n", plan) 99 fmt.Printf("AST: %s\n", ast) 100 } 101 102 func Example_createTable() { 103 ctx := context.TODO() 104 db, err := ydb.Open(ctx, "grpc://localhost:2136/local") 105 if err != nil { 106 fmt.Printf("failed connect: %v", err) 107 108 return 109 } 110 defer db.Close(ctx) // cleanup resources 111 err = db.Table().Do(ctx, 112 func(ctx context.Context, s table.Session) (err error) { 113 return s.CreateTable(ctx, path.Join(db.Name(), "series"), 114 options.WithColumn("series_id", types.Optional(types.TypeUint64)), 115 options.WithColumn("title", types.Optional(types.TypeText)), 116 options.WithColumn("series_info", types.Optional(types.TypeText)), 117 options.WithColumn("release_date", types.Optional(types.TypeDate)), 118 options.WithColumn("expire_at", types.Optional(types.TypeDate)), 119 options.WithColumn("comment", types.Optional(types.TypeText)), 120 options.WithPrimaryKeyColumn("series_id"), 121 options.WithTimeToLiveSettings( 122 options.NewTTLSettings().ColumnDateType("expire_at").ExpireAfter(time.Hour), 123 ), 124 options.WithIndex("idx_series_title", 125 options.WithIndexColumns("title"), 126 options.WithIndexType(options.GlobalAsyncIndex()), 127 ), 128 ) 129 }, 130 table.WithIdempotent(), 131 ) 132 if err != nil { 133 fmt.Printf("unexpected error: %v", err) 134 } 135 } 136 137 func Example_bulkUpsert() { 138 ctx := context.TODO() 139 db, err := ydb.Open(ctx, "grpc://localhost:2136/local") 140 if err != nil { 141 fmt.Printf("failed connect: %v", err) 142 143 return 144 } 145 defer db.Close(ctx) // cleanup resources 146 type logMessage struct { 147 App string 148 Host string 149 Timestamp time.Time 150 HTTPCode uint32 151 Message string 152 } 153 // prepare native go data 154 const batchSize = 10000 155 logs := make([]logMessage, 0, batchSize) 156 for i := 0; i < batchSize; i++ { 157 logs = append(logs, logMessage{ 158 App: fmt.Sprintf("App_%d", i/256), 159 Host: fmt.Sprintf("192.168.0.%d", i%256), 160 Timestamp: time.Now().Add(time.Millisecond * time.Duration(i%1000)), 161 HTTPCode: 200, 162 Message: "GET / HTTP/1.1", 163 }) 164 } 165 // execute bulk upsert with native ydb data 166 err = db.Table().Do( // Do retry operation on errors with best effort 167 ctx, // context manage exiting from Do 168 func(ctx context.Context, s table.Session) (err error) { // retry operation 169 rows := make([]types.Value, 0, len(logs)) 170 for _, msg := range logs { 171 rows = append(rows, types.StructValue( 172 types.StructFieldValue("App", types.TextValue(msg.App)), 173 types.StructFieldValue("Host", types.TextValue(msg.Host)), 174 types.StructFieldValue("Timestamp", types.TimestampValueFromTime(msg.Timestamp)), 175 types.StructFieldValue("HTTPCode", types.Uint32Value(msg.HTTPCode)), 176 types.StructFieldValue("Message", types.TextValue(msg.Message)), 177 )) 178 } 179 180 return s.BulkUpsert(ctx, "/local/bulk_upsert_example", types.ListValue(rows...)) 181 }, 182 table.WithIdempotent(), 183 ) 184 if err != nil { 185 fmt.Printf("unexpected error: %v", err) 186 } 187 } 188 189 func Example_alterTable() { 190 ctx := context.TODO() 191 db, err := ydb.Open(ctx, "grpc://localhost:2136/local") 192 if err != nil { 193 fmt.Printf("failed connect: %v", err) 194 195 return 196 } 197 defer db.Close(ctx) // cleanup resources 198 err = db.Table().Do(ctx, 199 func(ctx context.Context, s table.Session) (err error) { 200 return s.AlterTable(ctx, path.Join(db.Name(), "series"), 201 options.WithAddColumn("series_id", types.Optional(types.TypeUint64)), 202 options.WithAddColumn("title", types.Optional(types.TypeText)), 203 options.WithSetTimeToLiveSettings( 204 options.NewTTLSettings().ColumnDateType("expire_at").ExpireAfter(time.Hour), 205 ), 206 options.WithDropTimeToLive(), 207 options.WithAddIndex("idx_series_series_id", 208 options.WithIndexColumns("series_id"), 209 options.WithDataColumns("title"), 210 options.WithIndexType(options.GlobalIndex()), 211 ), 212 options.WithDropIndex("idx_series_title"), 213 options.WithAlterAttribute("hello", "world"), 214 options.WithAddAttribute("foo", "bar"), 215 options.WithDropAttribute("baz"), 216 ) 217 }, 218 table.WithIdempotent(), 219 ) 220 if err != nil { 221 fmt.Printf("unexpected error: %v", err) 222 } 223 } 224 225 func Example_lazyTransaction() { 226 ctx := context.TODO() 227 db, err := ydb.Open(ctx, "grpc://localhost:2136/local") 228 if err != nil { 229 fmt.Printf("failed connect: %v", err) 230 231 return 232 } 233 defer db.Close(ctx) 234 err = db.Table().Do(ctx, 235 func(ctx context.Context, session table.Session) (err error) { 236 // execute query with opening lazy transaction 237 tx, result, err := session.Execute(ctx, 238 table.SerializableReadWriteTxControl(), 239 "DECLARE $id AS Uint64; "+ 240 "SELECT `title`, `description` FROM `path/to/mytable` WHERE id = $id", 241 table.NewQueryParameters( 242 table.ValueParam("$id", types.Uint64Value(1)), 243 ), 244 ) 245 if err != nil { 246 return err 247 } 248 defer func() { 249 _ = tx.Rollback(ctx) 250 _ = result.Close() 251 }() 252 if !result.NextResultSet(ctx) { 253 return retry.RetryableError(fmt.Errorf("no result sets")) 254 } 255 if !result.NextRow() { 256 return retry.RetryableError(fmt.Errorf("no rows")) 257 } 258 var ( 259 id uint64 260 title string 261 description string 262 ) 263 if err = result.ScanNamed( 264 named.OptionalWithDefault("id", &id), 265 named.OptionalWithDefault("title", &title), 266 named.OptionalWithDefault("description", &description), 267 ); err != nil { 268 return err 269 } 270 fmt.Println(id, title, description) 271 // execute query with commit transaction 272 _, err = tx.Execute(ctx, 273 "DECLARE $id AS Uint64; "+ 274 "DECLARE $description AS Text; "+ 275 "UPSERT INTO `path/to/mytable` "+ 276 "(id, description) "+ 277 "VALUES ($id, $description);", 278 table.NewQueryParameters( 279 table.ValueParam("$id", types.Uint64Value(1)), 280 table.ValueParam("$description", types.TextValue("changed description")), 281 ), 282 options.WithCommit(), 283 ) 284 if err != nil { 285 return err 286 } 287 288 return result.Err() 289 }, 290 table.WithIdempotent(), 291 ) 292 if err != nil { 293 fmt.Printf("unexpected error: %v", err) 294 } 295 } 296 297 func Example_bulkUpsertWithCompression() { 298 ctx := context.TODO() 299 db, err := ydb.Open(ctx, "grpc://localhost:2136/local") 300 if err != nil { 301 fmt.Printf("failed connect: %v", err) 302 303 return 304 } 305 defer db.Close(ctx) // cleanup resources 306 type logMessage struct { 307 App string 308 Host string 309 Timestamp time.Time 310 HTTPCode uint32 311 Message string 312 } 313 // prepare native go data 314 const batchSize = 10000 315 logs := make([]logMessage, 0, batchSize) 316 for i := 0; i < batchSize; i++ { 317 logs = append(logs, logMessage{ 318 App: fmt.Sprintf("App_%d", i/256), 319 Host: fmt.Sprintf("192.168.0.%d", i%256), 320 Timestamp: time.Now().Add(time.Millisecond * time.Duration(i%1000)), 321 HTTPCode: 200, 322 Message: "GET /images/logo.png HTTP/1.1", 323 }) 324 } 325 // execute bulk upsert with native ydb data 326 err = db.Table().Do( // Do retry operation on errors with best effort 327 ctx, // context manage exiting from Do 328 func(ctx context.Context, s table.Session) (err error) { // retry operation 329 rows := make([]types.Value, 0, len(logs)) 330 for _, msg := range logs { 331 rows = append(rows, types.StructValue( 332 types.StructFieldValue("App", types.TextValue(msg.App)), 333 types.StructFieldValue("Host", types.TextValue(msg.Host)), 334 types.StructFieldValue("Timestamp", types.TimestampValueFromTime(msg.Timestamp)), 335 types.StructFieldValue("HTTPCode", types.Uint32Value(msg.HTTPCode)), 336 types.StructFieldValue("Message", types.TextValue(msg.Message)), 337 )) 338 } 339 340 return s.BulkUpsert(ctx, "/local/bulk_upsert_example", types.ListValue(rows...), 341 options.WithCallOptions(grpc.UseCompressor(gzip.Name)), 342 ) 343 }, 344 table.WithIdempotent(), 345 ) 346 if err != nil { 347 fmt.Printf("unexpected error: %v", err) 348 } 349 } 350 351 func Example_dataQueryWithCompression() { 352 ctx := context.TODO() 353 db, err := ydb.Open(ctx, "grpc://localhost:2136/local") 354 if err != nil { 355 fmt.Printf("failed connect: %v", err) 356 357 return 358 } 359 defer db.Close(ctx) // cleanup resources 360 var ( 361 query = `SELECT 42 as id, "my string" as myStr` 362 id int32 // required value 363 myStr string // optional value 364 ) 365 err = db.Table().Do( // Do retry operation on errors with best effort 366 ctx, // context manage exiting from Do 367 func(ctx context.Context, s table.Session) (err error) { // retry operation 368 _, res, err := s.Execute(ctx, table.DefaultTxControl(), query, nil, 369 options.WithCallOptions( 370 grpc.UseCompressor(gzip.Name), 371 ), 372 ) 373 if err != nil { 374 return err // for auto-retry with driver 375 } 376 defer res.Close() // cleanup resources 377 if err = res.NextResultSetErr(ctx); err != nil { // check single result set and switch to it 378 return err // for auto-retry with driver 379 } 380 for res.NextRow() { // iterate over rows 381 err = res.ScanNamed( 382 named.Required("id", &id), 383 named.OptionalWithDefault("myStr", &myStr), 384 ) 385 if err != nil { 386 return err // generally scan error not retryable, return it for driver check error 387 } 388 fmt.Printf("id=%v, myStr='%s'\n", id, myStr) 389 } 390 391 return res.Err() // return finally result error for auto-retry with driver 392 }, 393 table.WithIdempotent(), 394 ) 395 if err != nil { 396 fmt.Printf("unexpected error: %v", err) 397 } 398 } 399 400 func Example_scanQueryWithCompression() { 401 ctx := context.TODO() 402 db, err := ydb.Open(ctx, "grpc://localhost:2136/local") 403 if err != nil { 404 fmt.Printf("failed connect: %v", err) 405 406 return 407 } 408 defer db.Close(ctx) // cleanup resources 409 var ( 410 query = `SELECT 42 as id, "my string" as myStr` 411 id int32 // required value 412 myStr string // optional value 413 ) 414 err = db.Table().Do( // Do retry operation on errors with best effort 415 ctx, // context manage exiting from Do 416 func(ctx context.Context, s table.Session) (err error) { // retry operation 417 res, err := s.StreamExecuteScanQuery(ctx, query, nil, 418 options.WithCallOptions( 419 grpc.UseCompressor(gzip.Name), 420 ), 421 ) 422 if err != nil { 423 return err // for auto-retry with driver 424 } 425 defer res.Close() // cleanup resources 426 if err = res.NextResultSetErr(ctx); err != nil { // check single result set and switch to it 427 return err // for auto-retry with driver 428 } 429 for res.NextRow() { // iterate over rows 430 err = res.ScanNamed( 431 named.Required("id", &id), 432 named.OptionalWithDefault("myStr", &myStr), 433 ) 434 if err != nil { 435 return err // generally scan error not retryable, return it for driver check error 436 } 437 fmt.Printf("id=%v, myStr='%s'\n", id, myStr) 438 } 439 440 return res.Err() // return finally result error for auto-retry with driver 441 }, 442 table.WithIdempotent(), 443 ) 444 if err != nil { 445 fmt.Printf("unexpected error: %v", err) 446 } 447 } 448 449 func Example_copyTables() { 450 ctx := context.TODO() 451 db, err := ydb.Open(ctx, "grpc://localhost:2136/local") 452 if err != nil { 453 fmt.Printf("failed connect: %v", err) 454 455 return 456 } 457 defer db.Close(ctx) // cleanup resources 458 err = db.Table().Do(ctx, 459 func(ctx context.Context, s table.Session) (err error) { 460 return s.CopyTables(ctx, 461 options.CopyTablesItem( 462 path.Join(db.Name(), "from", "series"), 463 path.Join(db.Name(), "to", "series"), 464 true, 465 ), 466 ) 467 }, 468 table.WithIdempotent(), 469 ) 470 if err != nil { 471 fmt.Printf("unexpected error: %v", err) 472 } 473 }