github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/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, error) {
    42  	return &Client{
    43  		config:  config,
    44  		service: Ydb_Scheme_V1.NewSchemeServiceClient(cc),
    45  	}, nil
    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(""),
    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  	)
    68  }
    69  
    70  func (c *Client) makeDirectory(ctx context.Context, path string) (err error) {
    71  	_, err = c.service.MakeDirectory(
    72  		ctx,
    73  		&Ydb_Scheme.MakeDirectoryRequest{
    74  			Path: path,
    75  			OperationParams: operation.Params(
    76  				ctx,
    77  				c.config.OperationTimeout(),
    78  				c.config.OperationCancelAfter(),
    79  				operation.ModeSync,
    80  			),
    81  		},
    82  	)
    83  
    84  	return xerrors.WithStackTrace(err)
    85  }
    86  
    87  func (c *Client) RemoveDirectory(ctx context.Context, path string) (finalErr error) {
    88  	onDone := trace.SchemeOnRemoveDirectory(c.config.Trace(), &ctx,
    89  		stack.FunctionID(""),
    90  		path,
    91  	)
    92  	defer func() {
    93  		onDone(finalErr)
    94  	}()
    95  	call := func(ctx context.Context) error {
    96  		return xerrors.WithStackTrace(c.removeDirectory(ctx, path))
    97  	}
    98  	if !c.config.AutoRetry() {
    99  		return call(ctx)
   100  	}
   101  
   102  	return retry.Retry(ctx, call,
   103  		retry.WithStackTrace(),
   104  		retry.WithIdempotent(true),
   105  		retry.WithTrace(c.config.TraceRetry()),
   106  	)
   107  }
   108  
   109  func (c *Client) removeDirectory(ctx context.Context, path string) (err error) {
   110  	_, err = c.service.RemoveDirectory(
   111  		ctx,
   112  		&Ydb_Scheme.RemoveDirectoryRequest{
   113  			Path: path,
   114  			OperationParams: operation.Params(
   115  				ctx,
   116  				c.config.OperationTimeout(),
   117  				c.config.OperationCancelAfter(),
   118  				operation.ModeSync,
   119  			),
   120  		},
   121  	)
   122  
   123  	return xerrors.WithStackTrace(err)
   124  }
   125  
   126  func (c *Client) ListDirectory(ctx context.Context, path string) (d scheme.Directory, finalErr error) {
   127  	onDone := trace.SchemeOnListDirectory(c.config.Trace(), &ctx, stack.FunctionID(""))
   128  	defer func() {
   129  		onDone(finalErr)
   130  	}()
   131  	call := func(ctx context.Context) (err error) {
   132  		d, err = c.listDirectory(ctx, path)
   133  
   134  		return xerrors.WithStackTrace(err)
   135  	}
   136  	if !c.config.AutoRetry() {
   137  		err := call(ctx)
   138  
   139  		return d, xerrors.WithStackTrace(err)
   140  	}
   141  	err := retry.Retry(ctx, call,
   142  		retry.WithIdempotent(true),
   143  		retry.WithStackTrace(),
   144  		retry.WithTrace(c.config.TraceRetry()),
   145  	)
   146  
   147  	return d, xerrors.WithStackTrace(err)
   148  }
   149  
   150  func (c *Client) listDirectory(ctx context.Context, path string) (scheme.Directory, error) {
   151  	var (
   152  		d        scheme.Directory
   153  		err      error
   154  		response *Ydb_Scheme.ListDirectoryResponse
   155  		result   Ydb_Scheme.ListDirectoryResult
   156  	)
   157  	response, err = c.service.ListDirectory(
   158  		ctx,
   159  		&Ydb_Scheme.ListDirectoryRequest{
   160  			Path: path,
   161  			OperationParams: operation.Params(
   162  				ctx,
   163  				c.config.OperationTimeout(),
   164  				c.config.OperationCancelAfter(),
   165  				operation.ModeSync,
   166  			),
   167  		},
   168  	)
   169  	if err != nil {
   170  		return d, xerrors.WithStackTrace(err)
   171  	}
   172  	err = response.GetOperation().GetResult().UnmarshalTo(&result)
   173  	if err != nil {
   174  		return d, xerrors.WithStackTrace(err)
   175  	}
   176  	d.From(result.GetSelf())
   177  	d.Children = make([]scheme.Entry, len(result.GetChildren()))
   178  	putEntry(d.Children, result.GetChildren())
   179  
   180  	return d, nil
   181  }
   182  
   183  func (c *Client) DescribePath(ctx context.Context, path string) (e scheme.Entry, finalErr error) {
   184  	onDone := trace.SchemeOnDescribePath(c.config.Trace(), &ctx,
   185  		stack.FunctionID(""),
   186  		path,
   187  	)
   188  	defer func() {
   189  		onDone(e.Type.String(), finalErr)
   190  	}()
   191  	call := func(ctx context.Context) (err error) {
   192  		e, err = c.describePath(ctx, path)
   193  		if err != nil {
   194  			return xerrors.WithStackTrace(err)
   195  		}
   196  
   197  		return nil
   198  	}
   199  	if !c.config.AutoRetry() {
   200  		err := call(ctx)
   201  
   202  		return e, err
   203  	}
   204  	err := retry.Retry(ctx, call,
   205  		retry.WithIdempotent(true),
   206  		retry.WithStackTrace(),
   207  		retry.WithTrace(c.config.TraceRetry()),
   208  	)
   209  
   210  	return e, xerrors.WithStackTrace(err)
   211  }
   212  
   213  func (c *Client) describePath(ctx context.Context, path string) (e scheme.Entry, err error) {
   214  	var (
   215  		response *Ydb_Scheme.DescribePathResponse
   216  		result   Ydb_Scheme.DescribePathResult
   217  	)
   218  	response, err = c.service.DescribePath(
   219  		ctx,
   220  		&Ydb_Scheme.DescribePathRequest{
   221  			Path: path,
   222  			OperationParams: operation.Params(
   223  				ctx,
   224  				c.config.OperationTimeout(),
   225  				c.config.OperationCancelAfter(),
   226  				operation.ModeSync,
   227  			),
   228  		},
   229  	)
   230  	if err != nil {
   231  		return e, xerrors.WithStackTrace(err)
   232  	}
   233  	err = response.GetOperation().GetResult().UnmarshalTo(&result)
   234  	if err != nil {
   235  		return e, xerrors.WithStackTrace(err)
   236  	}
   237  	e.From(result.GetSelf())
   238  
   239  	return e, nil
   240  }
   241  
   242  func (c *Client) ModifyPermissions(
   243  	ctx context.Context, path string, opts ...scheme.PermissionsOption,
   244  ) (finalErr error) {
   245  	onDone := trace.SchemeOnModifyPermissions(c.config.Trace(), &ctx,
   246  		stack.FunctionID(""),
   247  		path,
   248  	)
   249  	defer func() {
   250  		onDone(finalErr)
   251  	}()
   252  	var desc permissionsDesc
   253  	for _, o := range opts {
   254  		if o != nil {
   255  			o(&desc)
   256  		}
   257  	}
   258  	call := func(ctx context.Context) error {
   259  		return xerrors.WithStackTrace(c.modifyPermissions(ctx, path, desc))
   260  	}
   261  	if !c.config.AutoRetry() {
   262  		return call(ctx)
   263  	}
   264  
   265  	return retry.Retry(ctx, call,
   266  		retry.WithStackTrace(),
   267  		retry.WithIdempotent(true),
   268  		retry.WithTrace(c.config.TraceRetry()),
   269  	)
   270  }
   271  
   272  func (c *Client) modifyPermissions(ctx context.Context, path string, desc permissionsDesc) (err error) {
   273  	_, err = c.service.ModifyPermissions(
   274  		ctx,
   275  		&Ydb_Scheme.ModifyPermissionsRequest{
   276  			Path:             path,
   277  			Actions:          desc.actions,
   278  			ClearPermissions: desc.clear,
   279  			OperationParams: operation.Params(
   280  				ctx,
   281  				c.config.OperationTimeout(),
   282  				c.config.OperationCancelAfter(),
   283  				operation.ModeSync,
   284  			),
   285  		},
   286  	)
   287  	if err != nil {
   288  		return xerrors.WithStackTrace(err)
   289  	}
   290  
   291  	return nil
   292  }
   293  
   294  func putEntry(dst []scheme.Entry, src []*Ydb_Scheme.Entry) {
   295  	for i, e := range src {
   296  		(dst[i]).From(e)
   297  	}
   298  }