github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/table/table.go (about)

     1  package table
     2  
     3  import (
     4  	"context"
     5  	"time"
     6  
     7  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Table"
     8  
     9  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/closer"
    10  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/params"
    11  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/types"
    12  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/value"
    13  	"github.com/ydb-platform/ydb-go-sdk/v3/retry"
    14  	"github.com/ydb-platform/ydb-go-sdk/v3/table/options"
    15  	"github.com/ydb-platform/ydb-go-sdk/v3/table/result"
    16  	"github.com/ydb-platform/ydb-go-sdk/v3/trace"
    17  )
    18  
    19  // Operation is the interface that holds an operation for retry.
    20  // if Operation returns not nil - operation will retry
    21  // if Operation returns nil - retry loop will break
    22  type Operation func(ctx context.Context, s Session) error
    23  
    24  // TxOperation is the interface that holds an operation for retry.
    25  // if TxOperation returns not nil - operation will retry
    26  // if TxOperation returns nil - retry loop will break
    27  type TxOperation func(ctx context.Context, tx TransactionActor) error
    28  
    29  type ClosableSession interface {
    30  	closer.Closer
    31  
    32  	Session
    33  }
    34  
    35  type Client interface {
    36  	// CreateSession returns session or error for manually control of session lifecycle
    37  	//
    38  	// CreateSession implements internal busy loop until one of the following conditions is met:
    39  	// - context was canceled or deadlined
    40  	// - session was created
    41  	//
    42  	// Deprecated: don't use CreateSession explicitly. This method only for ORM's compatibility.
    43  	// Use Do for queries with session
    44  	CreateSession(ctx context.Context, opts ...Option) (s ClosableSession, err error)
    45  
    46  	// Do provide the best effort for execute operation.
    47  	//
    48  	// Do implements internal busy loop until one of the following conditions is met:
    49  	// - deadline was canceled or deadlined
    50  	// - retry operation returned nil as error
    51  	//
    52  	// Warning: if context without deadline or cancellation func than Do can run indefinitely.
    53  	Do(ctx context.Context, op Operation, opts ...Option) error
    54  
    55  	// DoTx provide the best effort for execute transaction.
    56  	//
    57  	// DoTx implements internal busy loop until one of the following conditions is met:
    58  	// - deadline was canceled or deadlined
    59  	// - retry operation returned nil as error
    60  	//
    61  	// DoTx makes auto begin (with TxSettings, by default - SerializableReadWrite), commit and
    62  	// rollback (on error) of transaction.
    63  	//
    64  	// If op TxOperation returns nil - transaction will be committed
    65  	// If op TxOperation return non nil - transaction will be rollback
    66  	// Warning: if context without deadline or cancellation func than DoTx can run indefinitely
    67  	DoTx(ctx context.Context, op TxOperation, opts ...Option) error
    68  }
    69  
    70  type SessionStatus = string
    71  
    72  const (
    73  	SessionStatusUnknown = SessionStatus("unknown")
    74  	SessionReady         = SessionStatus("ready")
    75  	SessionBusy          = SessionStatus("busy")
    76  	SessionClosing       = SessionStatus("closing")
    77  	SessionClosed        = SessionStatus("closed")
    78  )
    79  
    80  type SessionInfo interface {
    81  	ID() string
    82  	NodeID() uint32
    83  	Status() SessionStatus
    84  	LastUsage() time.Time
    85  }
    86  
    87  type Session interface {
    88  	SessionInfo
    89  
    90  	CreateTable(
    91  		ctx context.Context,
    92  		path string,
    93  		opts ...options.CreateTableOption,
    94  	) (err error)
    95  
    96  	DescribeTable(
    97  		ctx context.Context,
    98  		path string,
    99  		opts ...options.DescribeTableOption,
   100  	) (desc options.Description, err error)
   101  
   102  	DropTable(
   103  		ctx context.Context,
   104  		path string,
   105  		opts ...options.DropTableOption,
   106  	) (err error)
   107  
   108  	AlterTable(
   109  		ctx context.Context,
   110  		path string,
   111  		opts ...options.AlterTableOption,
   112  	) (err error)
   113  
   114  	CopyTable(
   115  		ctx context.Context,
   116  		dst, src string,
   117  		opts ...options.CopyTableOption,
   118  	) (err error)
   119  
   120  	CopyTables(
   121  		ctx context.Context,
   122  		opts ...options.CopyTablesOption,
   123  	) (err error)
   124  
   125  	Explain(
   126  		ctx context.Context,
   127  		query string,
   128  	) (exp DataQueryExplanation, err error)
   129  
   130  	// Prepare prepares query for executing in the future
   131  	Prepare(
   132  		ctx context.Context,
   133  		query string,
   134  	) (stmt Statement, err error)
   135  
   136  	// Execute executes query.
   137  	//
   138  	// By default, Execute have a flag options.WithKeepInCache(true) if params is not empty. For redefine behavior -
   139  	// append option options.WithKeepInCache(false)
   140  	Execute(
   141  		ctx context.Context,
   142  		tx *TransactionControl,
   143  		query string,
   144  		params *params.Parameters,
   145  		opts ...options.ExecuteDataQueryOption,
   146  	) (txr Transaction, r result.Result, err error)
   147  
   148  	ExecuteSchemeQuery(
   149  		ctx context.Context,
   150  		query string,
   151  		opts ...options.ExecuteSchemeQueryOption,
   152  	) (err error)
   153  
   154  	DescribeTableOptions(
   155  		ctx context.Context,
   156  	) (desc options.TableOptionsDescription, err error)
   157  
   158  	StreamReadTable(
   159  		ctx context.Context,
   160  		path string,
   161  		opts ...options.ReadTableOption,
   162  	) (r result.StreamResult, err error)
   163  
   164  	StreamExecuteScanQuery(
   165  		ctx context.Context,
   166  		query string,
   167  		params *params.Parameters,
   168  		opts ...options.ExecuteScanQueryOption,
   169  	) (_ result.StreamResult, err error)
   170  
   171  	BulkUpsert(
   172  		ctx context.Context,
   173  		table string,
   174  		rows value.Value,
   175  		opts ...options.BulkUpsertOption,
   176  	) (err error)
   177  
   178  	ReadRows(
   179  		ctx context.Context,
   180  		path string,
   181  		keys value.Value,
   182  		opts ...options.ReadRowsOption,
   183  	) (_ result.Result, err error)
   184  
   185  	BeginTransaction(
   186  		ctx context.Context,
   187  		tx *TransactionSettings,
   188  	) (x Transaction, err error)
   189  
   190  	KeepAlive(
   191  		ctx context.Context,
   192  	) error
   193  }
   194  
   195  type TransactionSettings struct {
   196  	settings Ydb_Table.TransactionSettings
   197  }
   198  
   199  func (t *TransactionSettings) Settings() *Ydb_Table.TransactionSettings {
   200  	if t == nil {
   201  		return nil
   202  	}
   203  
   204  	return &t.settings
   205  }
   206  
   207  // Explanation is a result of Explain calls.
   208  type Explanation struct {
   209  	Plan string
   210  }
   211  
   212  // ScriptingYQLExplanation is a result of Explain calls.
   213  type ScriptingYQLExplanation struct {
   214  	Explanation
   215  
   216  	ParameterTypes map[string]types.Type
   217  }
   218  
   219  // DataQueryExplanation is a result of ExplainDataQuery call.
   220  type DataQueryExplanation struct {
   221  	Explanation
   222  
   223  	AST string
   224  }
   225  
   226  // DataQuery only for tracers
   227  type DataQuery interface {
   228  	String() string
   229  	ID() string
   230  	YQL() string
   231  }
   232  
   233  type TransactionIdentifier interface {
   234  	ID() string
   235  }
   236  
   237  type TransactionActor interface {
   238  	TransactionIdentifier
   239  
   240  	Execute(
   241  		ctx context.Context,
   242  		query string,
   243  		params *params.Parameters,
   244  		opts ...options.ExecuteDataQueryOption,
   245  	) (result.Result, error)
   246  	ExecuteStatement(
   247  		ctx context.Context,
   248  		stmt Statement,
   249  		params *params.Parameters,
   250  		opts ...options.ExecuteDataQueryOption,
   251  	) (result.Result, error)
   252  }
   253  
   254  type Transaction interface {
   255  	TransactionActor
   256  
   257  	CommitTx(
   258  		ctx context.Context,
   259  		opts ...options.CommitTransactionOption,
   260  	) (r result.Result, err error)
   261  	Rollback(
   262  		ctx context.Context,
   263  	) (err error)
   264  }
   265  
   266  type Statement interface {
   267  	Execute(
   268  		ctx context.Context,
   269  		tx *TransactionControl,
   270  		params *params.Parameters,
   271  		opts ...options.ExecuteDataQueryOption,
   272  	) (txr Transaction, r result.Result, err error)
   273  	NumInput() int
   274  	Text() string
   275  }
   276  
   277  var (
   278  	serializableReadWrite = &Ydb_Table.TransactionSettings_SerializableReadWrite{
   279  		SerializableReadWrite: &Ydb_Table.SerializableModeSettings{},
   280  	}
   281  	staleReadOnly = &Ydb_Table.TransactionSettings_StaleReadOnly{
   282  		StaleReadOnly: &Ydb_Table.StaleModeSettings{},
   283  	}
   284  	snapshotReadOnly = &Ydb_Table.TransactionSettings_SnapshotReadOnly{
   285  		SnapshotReadOnly: &Ydb_Table.SnapshotModeSettings{},
   286  	}
   287  )
   288  
   289  // Transaction control options
   290  type (
   291  	txDesc   Ydb_Table.TransactionSettings
   292  	TxOption func(*txDesc)
   293  )
   294  
   295  // TxSettings returns transaction settings
   296  func TxSettings(opts ...TxOption) *TransactionSettings {
   297  	s := new(TransactionSettings)
   298  	for _, opt := range opts {
   299  		if opt != nil {
   300  			opt((*txDesc)(&s.settings))
   301  		}
   302  	}
   303  
   304  	return s
   305  }
   306  
   307  // BeginTx returns begin transaction control option
   308  func BeginTx(opts ...TxOption) TxControlOption {
   309  	return func(d *txControlDesc) {
   310  		s := TxSettings(opts...)
   311  		d.TxSelector = &Ydb_Table.TransactionControl_BeginTx{
   312  			BeginTx: &s.settings,
   313  		}
   314  	}
   315  }
   316  
   317  func WithTx(t TransactionIdentifier) TxControlOption {
   318  	return func(d *txControlDesc) {
   319  		d.TxSelector = &Ydb_Table.TransactionControl_TxId{
   320  			TxId: t.ID(),
   321  		}
   322  	}
   323  }
   324  
   325  func WithTxID(txID string) TxControlOption {
   326  	return func(d *txControlDesc) {
   327  		d.TxSelector = &Ydb_Table.TransactionControl_TxId{
   328  			TxId: txID,
   329  		}
   330  	}
   331  }
   332  
   333  // CommitTx returns commit transaction control option
   334  func CommitTx() TxControlOption {
   335  	return func(d *txControlDesc) {
   336  		d.CommitTx = true
   337  	}
   338  }
   339  
   340  func WithSerializableReadWrite() TxOption {
   341  	return func(d *txDesc) {
   342  		d.TxMode = serializableReadWrite
   343  	}
   344  }
   345  
   346  func WithSnapshotReadOnly() TxOption {
   347  	return func(d *txDesc) {
   348  		d.TxMode = snapshotReadOnly
   349  	}
   350  }
   351  
   352  func WithStaleReadOnly() TxOption {
   353  	return func(d *txDesc) {
   354  		d.TxMode = staleReadOnly
   355  	}
   356  }
   357  
   358  func WithOnlineReadOnly(opts ...TxOnlineReadOnlyOption) TxOption {
   359  	return func(d *txDesc) {
   360  		var ro txOnlineReadOnly
   361  		for _, opt := range opts {
   362  			if opt != nil {
   363  				opt(&ro)
   364  			}
   365  		}
   366  		d.TxMode = &Ydb_Table.TransactionSettings_OnlineReadOnly{
   367  			OnlineReadOnly: (*Ydb_Table.OnlineModeSettings)(&ro),
   368  		}
   369  	}
   370  }
   371  
   372  type (
   373  	txOnlineReadOnly       Ydb_Table.OnlineModeSettings
   374  	TxOnlineReadOnlyOption func(*txOnlineReadOnly)
   375  )
   376  
   377  func WithInconsistentReads() TxOnlineReadOnlyOption {
   378  	return func(d *txOnlineReadOnly) {
   379  		d.AllowInconsistentReads = true
   380  	}
   381  }
   382  
   383  type (
   384  	txControlDesc   Ydb_Table.TransactionControl
   385  	TxControlOption func(*txControlDesc)
   386  )
   387  
   388  type TransactionControl struct {
   389  	desc Ydb_Table.TransactionControl
   390  }
   391  
   392  func (t *TransactionControl) Desc() *Ydb_Table.TransactionControl {
   393  	if t == nil {
   394  		return nil
   395  	}
   396  
   397  	return &t.desc
   398  }
   399  
   400  // TxControl makes transaction control from given options
   401  func TxControl(opts ...TxControlOption) *TransactionControl {
   402  	c := new(TransactionControl)
   403  	for _, opt := range opts {
   404  		if opt != nil {
   405  			opt((*txControlDesc)(&c.desc))
   406  		}
   407  	}
   408  
   409  	return c
   410  }
   411  
   412  // DefaultTxControl returns default transaction control with serializable read-write isolation mode and auto-commit
   413  func DefaultTxControl() *TransactionControl {
   414  	return TxControl(
   415  		BeginTx(WithSerializableReadWrite()),
   416  		CommitTx(),
   417  	)
   418  }
   419  
   420  // SerializableReadWriteTxControl returns transaction control with serializable read-write isolation mode
   421  func SerializableReadWriteTxControl(opts ...TxControlOption) *TransactionControl {
   422  	return TxControl(
   423  		append([]TxControlOption{
   424  			BeginTx(WithSerializableReadWrite()),
   425  		}, opts...)...,
   426  	)
   427  }
   428  
   429  // OnlineReadOnlyTxControl returns online read-only transaction control
   430  func OnlineReadOnlyTxControl(opts ...TxOnlineReadOnlyOption) *TransactionControl {
   431  	return TxControl(
   432  		BeginTx(WithOnlineReadOnly(opts...)),
   433  		CommitTx(), // open transactions not supported for OnlineReadOnly
   434  	)
   435  }
   436  
   437  // StaleReadOnlyTxControl returns stale read-only transaction control
   438  func StaleReadOnlyTxControl() *TransactionControl {
   439  	return TxControl(
   440  		BeginTx(WithStaleReadOnly()),
   441  		CommitTx(), // open transactions not supported for StaleReadOnly
   442  	)
   443  }
   444  
   445  // SnapshotReadOnlyTxControl returns snapshot read-only transaction control
   446  func SnapshotReadOnlyTxControl() *TransactionControl {
   447  	return TxControl(
   448  		BeginTx(WithSnapshotReadOnly()),
   449  		CommitTx(), // open transactions not supported for StaleReadOnly
   450  	)
   451  }
   452  
   453  // QueryParameters
   454  type (
   455  	ParameterOption = params.NamedValue
   456  	QueryParameters = params.Parameters
   457  )
   458  
   459  func NewQueryParameters(opts ...ParameterOption) *QueryParameters {
   460  	qp := QueryParameters(make([]*params.Parameter, len(opts)))
   461  	for i, opt := range opts {
   462  		qp[i] = params.Named(opt.Name(), opt.Value())
   463  	}
   464  
   465  	return &qp
   466  }
   467  
   468  func ValueParam(name string, v value.Value) ParameterOption {
   469  	switch len(name) {
   470  	case 0:
   471  		panic("empty name")
   472  	default:
   473  		if name[0] != '$' {
   474  			name = "$" + name
   475  		}
   476  	}
   477  
   478  	return params.Named(name, v)
   479  }
   480  
   481  type Options struct {
   482  	Label           string
   483  	Idempotent      bool
   484  	TxSettings      *TransactionSettings
   485  	TxCommitOptions []options.CommitTransactionOption
   486  	RetryOptions    []retry.Option
   487  	Trace           *trace.Table
   488  }
   489  
   490  type Option interface {
   491  	ApplyTableOption(opts *Options)
   492  }
   493  
   494  var _ Option = labelOption("")
   495  
   496  type labelOption string
   497  
   498  func (label labelOption) ApplyTableOption(opts *Options) {
   499  	opts.Label = string(label)
   500  	opts.RetryOptions = append(opts.RetryOptions, retry.WithLabel(string(label)))
   501  }
   502  
   503  func WithLabel(label string) labelOption {
   504  	return labelOption(label)
   505  }
   506  
   507  var _ Option = retryOptionsOption{}
   508  
   509  type retryOptionsOption []retry.Option
   510  
   511  func (retryOptions retryOptionsOption) ApplyTableOption(opts *Options) {
   512  	opts.RetryOptions = append(opts.RetryOptions, retry.WithIdempotent(true))
   513  }
   514  
   515  func WithRetryOptions(retryOptions []retry.Option) retryOptionsOption {
   516  	return retryOptions
   517  }
   518  
   519  var _ Option = idempotentOption{}
   520  
   521  type idempotentOption struct{}
   522  
   523  func (idempotentOption) ApplyTableOption(opts *Options) {
   524  	opts.Idempotent = true
   525  	opts.RetryOptions = append(opts.RetryOptions, retry.WithIdempotent(true))
   526  }
   527  
   528  func WithIdempotent() idempotentOption {
   529  	return idempotentOption{}
   530  }
   531  
   532  var _ Option = txSettingsOption{}
   533  
   534  type txSettingsOption struct {
   535  	txSettings *TransactionSettings
   536  }
   537  
   538  func (opt txSettingsOption) ApplyTableOption(opts *Options) {
   539  	opts.TxSettings = opt.txSettings
   540  }
   541  
   542  func WithTxSettings(txSettings *TransactionSettings) txSettingsOption {
   543  	return txSettingsOption{txSettings: txSettings}
   544  }
   545  
   546  var _ Option = txCommitOptionsOption(nil)
   547  
   548  type txCommitOptionsOption []options.CommitTransactionOption
   549  
   550  func (txCommitOpts txCommitOptionsOption) ApplyTableOption(opts *Options) {
   551  	opts.TxCommitOptions = append(opts.TxCommitOptions, txCommitOpts...)
   552  }
   553  
   554  func WithTxCommitOptions(opts ...options.CommitTransactionOption) txCommitOptionsOption {
   555  	return opts
   556  }
   557  
   558  var _ Option = traceOption{}
   559  
   560  type traceOption struct {
   561  	t *trace.Table
   562  }
   563  
   564  func (opt traceOption) ApplyTableOption(opts *Options) {
   565  	opts.Trace = opts.Trace.Compose(opt.t)
   566  }
   567  
   568  func WithTrace(t trace.Table) traceOption { //nolint:gocritic
   569  	return traceOption{t: &t}
   570  }