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  }