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