Skip to content

Commit ee359f9

Browse files
Export function to initialize Config with defaults (go-sql-driver#679)
* dsn: export NewConfig * dsn: move DSN normalization to separate func * dsn: add godoc * dsn: add missing return
1 parent a8b7ed4 commit ee359f9

File tree

2 files changed

+44
-30
lines changed

2 files changed

+44
-30
lines changed

dsn.go

+43-30
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ var (
2828
errInvalidDSNUnsafeCollation = errors.New("invalid DSN: interpolateParams can not be used with unsafe collations")
2929
)
3030

31-
// Config is a configuration parsed from a DSN string
31+
// Config is a configuration parsed from a DSN string.
32+
// If a new Config is created instead of being parsed from a DSN string,
33+
// the NewConfig function should be used, which sets default values.
3234
type Config struct {
3335
User string // Username
3436
Passwd string // Password (requires User)
@@ -57,6 +59,43 @@ type Config struct {
5759
RejectReadOnly bool // Reject read-only connections
5860
}
5961

62+
// NewConfig creates a new Config and sets default values.
63+
func NewConfig() *Config {
64+
return &Config{
65+
Collation: defaultCollation,
66+
Loc: time.UTC,
67+
AllowNativePasswords: true,
68+
}
69+
}
70+
71+
func (cfg *Config) normalize() error {
72+
if cfg.InterpolateParams && unsafeCollations[cfg.Collation] {
73+
return errInvalidDSNUnsafeCollation
74+
}
75+
76+
// Set default network if empty
77+
if cfg.Net == "" {
78+
cfg.Net = "tcp"
79+
}
80+
81+
// Set default address if empty
82+
if cfg.Addr == "" {
83+
switch cfg.Net {
84+
case "tcp":
85+
cfg.Addr = "127.0.0.1:3306"
86+
case "unix":
87+
cfg.Addr = "/tmp/mysql.sock"
88+
default:
89+
return errors.New("default addr for network '" + cfg.Net + "' unknown")
90+
}
91+
92+
} else if cfg.Net == "tcp" {
93+
cfg.Addr = ensureHavePort(cfg.Addr)
94+
}
95+
96+
return nil
97+
}
98+
6099
// FormatDSN formats the given Config into a DSN string which can be passed to
61100
// the driver.
62101
func (cfg *Config) FormatDSN() string {
@@ -273,11 +312,7 @@ func (cfg *Config) FormatDSN() string {
273312
// ParseDSN parses the DSN string to a Config
274313
func ParseDSN(dsn string) (cfg *Config, err error) {
275314
// New config with some default values
276-
cfg = &Config{
277-
Loc: time.UTC,
278-
Collation: defaultCollation,
279-
AllowNativePasswords: true,
280-
}
315+
cfg = NewConfig()
281316

282317
// [user[:password]@][net[(addr)]]/dbname[?param1=value1&paramN=valueN]
283318
// Find the last '/' (since the password or the net addr might contain a '/')
@@ -345,31 +380,9 @@ func ParseDSN(dsn string) (cfg *Config, err error) {
345380
return nil, errInvalidDSNNoSlash
346381
}
347382

348-
if cfg.InterpolateParams && unsafeCollations[cfg.Collation] {
349-
return nil, errInvalidDSNUnsafeCollation
350-
}
351-
352-
// Set default network if empty
353-
if cfg.Net == "" {
354-
cfg.Net = "tcp"
383+
if err = cfg.normalize(); err != nil {
384+
return nil, err
355385
}
356-
357-
// Set default address if empty
358-
if cfg.Addr == "" {
359-
switch cfg.Net {
360-
case "tcp":
361-
cfg.Addr = "127.0.0.1:3306"
362-
case "unix":
363-
cfg.Addr = "/tmp/mysql.sock"
364-
default:
365-
return nil, errors.New("default addr for network '" + cfg.Net + "' unknown")
366-
}
367-
368-
}
369-
if cfg.Net == "tcp" {
370-
cfg.Addr = ensureHavePort(cfg.Addr)
371-
}
372-
373386
return
374387
}
375388

dsn_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ func TestDSNParserInvalid(t *testing.T) {
9898
"(/", // no closing brace
9999
"net(addr)//", // unescaped
100100
"User:pass@tcp(1.2.3.4:3306)", // no trailing slash
101+
"net()/", // unknown default addr
101102
//"/dbname?arg=/some/unescaped/path",
102103
}
103104

0 commit comments

Comments
 (0)