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

     1  package dsn
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"regexp"
     7  
     8  	"github.com/ydb-platform/ydb-go-sdk/v3/config"
     9  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors"
    10  )
    11  
    12  var (
    13  	insecureSchema = "grpc"
    14  	secureSchema   = "grpcs"
    15  	reScheme       = regexp.MustCompile(`^\w+://`)
    16  	databaseParam  = "database"
    17  )
    18  
    19  type UserInfo struct {
    20  	User     string
    21  	Password string
    22  }
    23  
    24  type parsedInfo struct {
    25  	UserInfo *UserInfo
    26  	Options  []config.Option
    27  	Params   url.Values
    28  }
    29  
    30  func Parse(dsn string) (info parsedInfo, err error) {
    31  	uri, err := url.ParseRequestURI(func() string {
    32  		if reScheme.MatchString(dsn) {
    33  			return dsn
    34  		}
    35  
    36  		return secureSchema + "://" + dsn
    37  	}())
    38  	if err != nil {
    39  		return info, xerrors.WithStackTrace(err)
    40  	}
    41  	if port := uri.Port(); port == "" {
    42  		return info, xerrors.WithStackTrace(fmt.Errorf("bad connection string '%s': port required", dsn))
    43  	}
    44  	info.Options = append(info.Options,
    45  		config.WithSecure(uri.Scheme != insecureSchema),
    46  		config.WithEndpoint(uri.Host),
    47  	)
    48  	if uri.Path != "" {
    49  		info.Options = append(info.Options, config.WithDatabase(uri.Path))
    50  	}
    51  	if uri.User != nil {
    52  		password, _ := uri.User.Password()
    53  		info.UserInfo = &UserInfo{
    54  			User:     uri.User.Username(),
    55  			Password: password,
    56  		}
    57  	}
    58  	info.Params = uri.Query()
    59  	if database, has := info.Params[databaseParam]; has && len(database) > 0 {
    60  		info.Options = append(info.Options,
    61  			config.WithDatabase(database[0]),
    62  		)
    63  		delete(info.Params, databaseParam)
    64  	}
    65  
    66  	return info, nil
    67  }