@@ -11,20 +11,22 @@ type Config struct {
1111 Passwd string
1212 Addr string
1313 DBName string
14+ Auth string
1415}
1516
1617var (
1718 // Regexp syntax: https://github.com/google/re2/wiki/Syntax
18- reDSN = regexp .MustCompile (`(.+@)?([^@]+ )` )
19+ reDSN = regexp .MustCompile (`(.+@)?([^@|^?]+)\\?(.* )` )
1920 reUserPasswd = regexp .MustCompile (`([^:@]+)(:[^:@]+)?@` )
21+ reArguments = regexp .MustCompile (`(\w+)=(\w+)` )
2022)
2123
2224// ParseDSN requires DSN names in the format [user[:password]@]addr/dbname.
2325func ParseDSN (dsn string ) (* Config , error ) {
2426 // Please read https://play.golang.org/p/_CSLvl1AxOX before code review.
2527 sub := reDSN .FindStringSubmatch (dsn )
26- if len (sub ) != 3 {
27- return nil , fmt .Errorf ("The DSN %s doesn't match [user[:password]@]addr[/dbname]" , dsn )
28+ if len (sub ) != 4 {
29+ return nil , fmt .Errorf ("The DSN %s doesn't match [user[:password]@]addr[/dbname][?auth=AUTH_MECHANISM] " , dsn )
2830 }
2931 addr := ""
3032 dbname := ""
@@ -35,21 +37,45 @@ func ParseDSN(dsn string) (*Config, error) {
3537 } else {
3638 addr = sub [2 ]
3739 }
40+ user := ""
41+ passwd := ""
42+ auth := "NOSASL"
3843 up := reUserPasswd .FindStringSubmatch (sub [1 ])
3944 if len (up ) == 3 {
45+ user = up [1 ]
4046 if len (up [2 ]) > 0 {
41- return & Config { User : up [1 ], Passwd : up [ 2 ][1 :], Addr : addr , DBName : dbname }, nil
47+ passwd = up [2 ][1 :]
4248 }
43- return & Config {User : up [1 ], Addr : addr , DBName : dbname }, nil
4449 }
45- return & Config {Addr : addr , DBName : dbname }, nil
50+
51+ args := reArguments .FindAllStringSubmatch (sub [3 ], - 1 )
52+ if len (args ) > 1 {
53+ return nil , fmt .Errorf ("The DSN %s doesn't match [user[:password]@]addr[/dbname][?auth=AUTH_MECHANISM]" , dsn )
54+ }
55+
56+ if len (args ) == 1 {
57+ if args [0 ][1 ] != "auth" {
58+ return nil , fmt .Errorf ("The DSN %s doesn't match [user[:password]@]addr[/dbname][?auth=AUTH_MECHANISM]" , dsn )
59+ }
60+ auth = args [0 ][2 ]
61+ }
62+ return & Config {
63+ User : user ,
64+ Passwd : passwd ,
65+ Addr : addr ,
66+ DBName : dbname ,
67+ Auth : auth ,
68+ }, nil
4669}
4770
48- // FormatDSN outputs a string in the format "user:password@address"
71+ // FormatDSN outputs a string in the format "user:password@address?auth=xxx "
4972func (cfg * Config ) FormatDSN () string {
73+ dsn := fmt .Sprintf ("%s:%s@%s" , cfg .User , cfg .Passwd , cfg .Addr )
5074 if len (cfg .DBName ) > 0 {
51- return fmt .Sprintf ("%s:%s@%s/%s" , cfg .User , cfg .Passwd , cfg .Addr , cfg .DBName )
52- } else {
53- return fmt .Sprintf ("%s:%s@%s" , cfg .User , cfg .Passwd , cfg .Addr )
75+ dsn = fmt .Sprintf ("%s/%s" , dsn , cfg .DBName )
76+ }
77+ if len (cfg .Auth ) > 0 {
78+ dsn = fmt .Sprintf ("%s?auth=%s" , dsn , cfg .Auth )
5479 }
80+ return dsn
5581}
0 commit comments