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  }