github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/internal/scheme/helpers/check_exists.go (about) 1 package helpers 2 3 import ( 4 "context" 5 "fmt" 6 "path" 7 "strings" 8 9 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors" 10 "github.com/ydb-platform/ydb-go-sdk/v3/scheme" 11 ) 12 13 type schemeClient interface { 14 Database() string 15 ListDirectory(ctx context.Context, path string) (d scheme.Directory, err error) 16 } 17 18 func IsDirectoryExists(ctx context.Context, c schemeClient, directory string) ( 19 exists bool, _ error, 20 ) { 21 if !strings.HasPrefix(directory, c.Database()) { 22 return false, xerrors.WithStackTrace(fmt.Errorf( 23 "path '%s' must be inside database '%s'", 24 directory, c.Database(), 25 )) 26 } 27 if directory == c.Database() { 28 return true, nil 29 } 30 parentDirectory, childDirectory := path.Split(directory) 31 parentDirectory = strings.TrimRight(parentDirectory, "/") 32 33 if exists, err := IsDirectoryExists(ctx, c, parentDirectory); err != nil { 34 return false, xerrors.WithStackTrace(err) 35 } else if !exists { 36 return false, nil 37 } 38 39 d, err := c.ListDirectory(ctx, parentDirectory) 40 if err != nil { 41 return false, xerrors.WithStackTrace(err) 42 } 43 for i := range d.Children { 44 if d.Children[i].Name != childDirectory { 45 continue 46 } 47 if t := d.Children[i].Type; t != scheme.EntryDirectory { 48 return false, xerrors.WithStackTrace(fmt.Errorf( 49 "entry '%s' in path '%s' is not a directory: %s", 50 childDirectory, parentDirectory, t.String(), 51 )) 52 } 53 54 return true, nil 55 } 56 57 return false, nil 58 } 59 60 func IsEntryExists(ctx context.Context, c schemeClient, absPath string, entryTypes ...scheme.EntryType) ( 61 exists bool, _ error, 62 ) { 63 if !strings.HasPrefix(absPath, c.Database()) { 64 return false, xerrors.WithStackTrace(fmt.Errorf( 65 "entry path '%s' must be inside database '%s'", 66 absPath, c.Database(), 67 )) 68 } else if absPath == c.Database() { 69 return false, xerrors.WithStackTrace(fmt.Errorf( 70 "entry path '%s' cannot be equals database name '%s'", 71 absPath, c.Database(), 72 )) 73 } 74 directory, entryName := path.Split(absPath) 75 if exists, err := IsDirectoryExists(ctx, c, strings.TrimRight(directory, "/")); err != nil { 76 return false, xerrors.WithStackTrace(err) 77 } else if !exists { 78 return false, nil 79 } 80 d, err := c.ListDirectory(ctx, directory) 81 if err != nil { 82 return false, xerrors.WithStackTrace(fmt.Errorf( 83 "list directory '%s' failed: %w", 84 directory, err, 85 )) 86 } 87 for i := range d.Children { 88 if d.Children[i].Name != entryName { 89 continue 90 } 91 childrenType := d.Children[i].Type 92 for _, entryType := range entryTypes { 93 if childrenType == entryType { 94 return true, nil 95 } 96 } 97 98 return false, xerrors.WithStackTrace(fmt.Errorf( 99 "entry type of '%s' (%s) in path '%s' is not corresponds to %v", 100 entryName, childrenType, directory, entryTypes, 101 )) 102 } 103 104 return false, nil 105 }