github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/internal/scheme/client.go (about)

     1  package scheme
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  
     7  	"github.com/ydb-platform/ydb-go-genproto/Ydb_Scheme_V1"
     8  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Scheme"
     9  	"google.golang.org/grpc"
    10  
    11  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/operation"
    12  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/scheme/config"
    13  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/stack"
    14  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors"
    15  	"github.com/ydb-platform/ydb-go-sdk/v3/retry"
    16  	"github.com/ydb-platform/ydb-go-sdk/v3/scheme"
    17  	"github.com/ydb-platform/ydb-go-sdk/v3/trace"
    18  )
    19  
    20  //nolint:gofumpt
    21  //nolint:nolintlint
    22  var errNilClient = xerrors.Wrap(errors.New("scheme client is not initialized"))
    23  
    24  type Client struct {
    25  	config  *config.Config
    26  	service Ydb_Scheme_V1.SchemeServiceClient
    27  }
    28  
    29  func (c *Client) Database() string {
    30  	return c.config.Database()
    31  }
    32  
    33  func (c *Client) Close(_ context.Context) error {
    34  	if c == nil {
    35  		return xerrors.WithStackTrace(errNilClient)
    36  	}
    37  
    38  	return nil
    39  }
    40  
    41  func New(ctx context.Context, cc grpc.ClientConnInterface, config *config.Config) *Client {
    42  	return &Client{
    43  		config:  config,
    44  		service: Ydb_Scheme_V1.NewSchemeServiceClient(cc),
    45  	}
    46  }
    47  
    48  func (c *Client) MakeDirectory(ctx context.Context, path string) (finalErr error) {
    49  	onDone := trace.SchemeOnMakeDirectory(c.config.Trace(), &ctx,
    50  		stack.FunctionID("github.com/ydb-platform/ydb-go-sdk/v3/internal/scheme.(*Client).MakeDirectory"),
    51  		path,
    52  	)
    53  	defer func() {
    54  		onDone(finalErr)
    55  	}()
    56  	call := func(ctx context.Context) error {
    57  		return xerrors.WithStackTrace(c.makeDirectory(ctx, path))
    58  	}
    59  	if !c.config.AutoRetry() {
    60  		return call(ctx)
    61  	}
    62  
    63  	return retry.Retry(ctx, call,
    64  		retry.WithStackTrace(),
    65  		retry.WithIdempotent(true),
    66  		retry.WithTrace(c.config.TraceRetry()),
    67  		retry.WithBudget(c.config.RetryBudget()),
    68  	)
    69  }
    70  
    71  func (c *Client) makeDirectory(ctx context.Context, path string) (err error) {
    72  	_, err = c.service.MakeDirectory(
    73  		ctx,
    74  		&Ydb_Scheme.MakeDirectoryRequest{
    75  			Path: path,
    76  			OperationParams: operation.Params(
    77  				ctx,
    78  				c.config.OperationTimeout(),
    79  				c.config.OperationCancelAfter(),
    80  				operation.ModeSync,
    81  			),
    82  		},
    83  	)
    84  
    85  	return xerrors.WithStackTrace(err)
    86  }
    87  
    88  func (c *Client) RemoveDirectory(ctx context.Context, path string) (finalErr error) {
    89  	onDone := trace.SchemeOnRemoveDirectory(c.config.Trace(), &ctx,
    90  		stack.FunctionID("github.com/ydb-platform/ydb-go-sdk/v3/internal/scheme.(*Client).RemoveDirectory"),
    91  		path,
    92  	)
    93  	defer func() {
    94  		onDone(finalErr)
    95  	}()
    96  	call := func(ctx context.Context) error {
    97  		return xerrors.WithStackTrace(c.removeDirectory(ctx, path))
    98  	}
    99  	if !c.config.AutoRetry() {
   100  		return call(ctx)
   101  	}
   102  
   103  	return retry.Retry(ctx, call,
   104  		retry.WithStackTrace(),
   105  		retry.WithIdempotent(true),
   106  		retry.WithTrace(c.config.TraceRetry()),
   107  		retry.WithBudget(c.config.RetryBudget()),
   108  	)
   109  }
   110  
   111  func (c *Client) removeDirectory(ctx context.Context, path string) (err error) {
   112  	_, err = c.service.RemoveDirectory(
   113  		ctx,
   114  		&Ydb_Scheme.RemoveDirectoryRequest{
   115  			Path: path,
   116  			OperationParams: operation.Params(
   117  				ctx,
   118  				c.config.OperationTimeout(),
   119  				c.config.OperationCancelAfter(),
   120  				operation.ModeSync,
   121  			),
   122  		},
   123  	)
   124  
   125  	return xerrors.WithStackTrace(err)
   126  }
   127  
   128  func (c *Client) ListDirectory(ctx context.Context, path string) (d scheme.Directory, finalErr error) {
   129  	onDone := trace.SchemeOnListDirectory(c.config.Trace(), &ctx,
   130  		stack.FunctionID("github.com/ydb-platform/ydb-go-sdk/v3/internal/scheme.(*Client).ListDirectory"),
   131  	)
   132  	defer func() {
   133  		onDone(finalErr)
   134  	}()
   135  	call := func(ctx context.Context) (err error) {
   136  		d, err = c.listDirectory(ctx, path)
   137  
   138  		return xerrors.WithStackTrace(err)
   139  	}
   140  	if !c.config.AutoRetry() {
   141  		err := call(ctx)
   142  
   143  		return d, xerrors.WithStackTrace(err)
   144  	}
   145  	err := retry.Retry(ctx, call,
   146  		retry.WithIdempotent(true),
   147  		retry.WithStackTrace(),
   148  		retry.WithTrace(c.config.TraceRetry()),
   149  		retry.WithBudget(c.config.RetryBudget()),
   150  	)
   151  
   152  	return d, xerrors.WithStackTrace(err)
   153  }
   154  
   155  func (c *Client) listDirectory(ctx context.Context, path string) (scheme.Directory, error) {
   156  	var (
   157  		d        scheme.Directory
   158  		err      error
   159  		response *Ydb_Scheme.ListDirectoryResponse
   160  		result   Ydb_Scheme.ListDirectoryResult
   161  	)
   162  	response, err = c.service.ListDirectory(
   163  		ctx,
   164  		&Ydb_Scheme.ListDirectoryRequest{
   165  			Path: path,
   166  			OperationParams: operation.Params(
   167  				ctx,
   168  				c.config.OperationTimeout(),
   169  				c.config.OperationCancelAfter(),
   170  				operation.ModeSync,
   171  			),
   172  		},
   173  	)
   174  	if err != nil {
   175  		return d, xerrors.WithStackTrace(err)
   176  	}
   177  	err = response.GetOperation().GetResult().UnmarshalTo(&result)
   178  	if err != nil {
   179  		return d, xerrors.WithStackTrace(err)
   180  	}
   181  	d.From(result.GetSelf())
   182  	d.Children = make([]scheme.Entry, len(result.GetChildren()))
   183  	putEntry(d.Children, result.GetChildren())
   184  
   185  	return d, nil
   186  }
   187  
   188  func (c *Client) DescribePath(ctx context.Context, path string) (e scheme.Entry, finalErr error) {
   189  	onDone := trace.SchemeOnDescribePath(c.config.Trace(), &ctx,
   190  		stack.FunctionID("github.com/ydb-platform/ydb-go-sdk/v3/internal/scheme.(*Client).DescribePath"),
   191  		path,
   192  	)
   193  	defer func() {
   194  		onDone(e.Type.String(), finalErr)
   195  	}()
   196  	call := func(ctx context.Context) (err error) {
   197  		e, err = c.describePath(ctx, path)
   198  		if err != nil {
   199  			return xerrors.WithStackTrace(err)
   200  		}
   201  
   202  		return nil
   203  	}
   204  	if !c.config.AutoRetry() {
   205  		err := call(ctx)
   206  
   207  		return e, err
   208  	}
   209  	err := retry.Retry(ctx, call,
   210  		retry.WithIdempotent(true),
   211  		retry.WithStackTrace(),
   212  		retry.WithTrace(c.config.TraceRetry()),
   213  		retry.WithBudget(c.config.RetryBudget()),
   214  	)
   215  
   216  	return e, xerrors.WithStackTrace(err)
   217  }
   218  
   219  func (c *Client) describePath(ctx context.Context, path string) (e scheme.Entry, err error) {
   220  	var (
   221  		response *Ydb_Scheme.DescribePathResponse
   222  		result   Ydb_Scheme.DescribePathResult
   223  	)
   224  	response, err = c.service.DescribePath(
   225  		ctx,
   226  		&Ydb_Scheme.DescribePathRequest{
   227  			Path: path,
   228  			OperationParams: operation.Params(
   229  				ctx,
   230  				c.config.OperationTimeout(),
   231  				c.config.OperationCancelAfter(),
   232  				operation.ModeSync,
   233  			),
   234  		},
   235  	)
   236  	if err != nil {
   237  		return e, xerrors.WithStackTrace(err)
   238  	}
   239  	err = response.GetOperation().GetResult().UnmarshalTo(&result)
   240  	if err != nil {
   241  		return e, xerrors.WithStackTrace(err)
   242  	}
   243  	e.From(result.GetSelf())
   244  
   245  	return e, nil
   246  }
   247  
   248  func (c *Client) ModifyPermissions(
   249  	ctx context.Context, path string, opts ...scheme.PermissionsOption,
   250  ) (finalErr error) {
   251  	onDone := trace.SchemeOnModifyPermissions(c.config.Trace(), &ctx,
   252  		stack.FunctionID("github.com/ydb-platform/ydb-go-sdk/v3/internal/scheme.(*Client).ModifyPermissions"),
   253  		path,
   254  	)
   255  	defer func() {
   256  		onDone(finalErr)
   257  	}()
   258  	var desc permissionsDesc
   259  	for _, opt := range opts {
   260  		if opt != nil {
   261  			opt(&desc)
   262  		}
   263  	}
   264  	call := func(ctx context.Context) error {
   265  		return xerrors.WithStackTrace(c.modifyPermissions(ctx, path, desc))
   266  	}
   267  	if !c.config.AutoRetry() {
   268  		return call(ctx)
   269  	}
   270  
   271  	return retry.Retry(ctx, call,
   272  		retry.WithStackTrace(),
   273  		retry.WithIdempotent(true),
   274  		retry.WithTrace(c.config.TraceRetry()),
   275  		retry.WithBudget(c.config.RetryBudget()),
   276  	)
   277  }
   278  
   279  func (c *Client) modifyPermissions(ctx context.Context, path string, desc permissionsDesc) (err error) {
   280  	_, err = c.service.ModifyPermissions(
   281  		ctx,
   282  		&Ydb_Scheme.ModifyPermissionsRequest{
   283  			Path:             path,
   284  			Actions:          desc.actions,
   285  			ClearPermissions: desc.clear,
   286  			OperationParams: operation.Params(
   287  				ctx,
   288  				c.config.OperationTimeout(),
   289  				c.config.OperationCancelAfter(),
   290  				operation.ModeSync,
   291  			),
   292  		},
   293  	)
   294  	if err != nil {
   295  		return xerrors.WithStackTrace(err)
   296  	}
   297  
   298  	return nil
   299  }
   300  
   301  func putEntry(dst []scheme.Entry, src []*Ydb_Scheme.Entry) {
   302  	for i, e := range src {
   303  		(dst[i]).From(e)
   304  	}
   305  }