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 }