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 }