34
34
// If a new Config is created instead of being parsed from a DSN string,
35
35
// the NewConfig function should be used, which sets default values.
36
36
type Config struct {
37
+ // non boolean fields
38
+
37
39
User string // Username
38
40
Passwd string // Password (requires User)
39
41
Net string // Network (e.g. "tcp", "tcp6", "unix". default: "tcp")
@@ -45,15 +47,15 @@ type Config struct {
45
47
Loc * time.Location // Location for time.Time values
46
48
MaxAllowedPacket int // Max packet size allowed
47
49
ServerPubKey string // Server public key name
48
- pubKey * rsa.PublicKey // Server public key
49
50
TLSConfig string // TLS configuration name
50
51
TLS * tls.Config // TLS configuration, its priority is higher than TLSConfig
51
- TimeTruncate time.Duration // Truncate time.Time values to the specified duration
52
52
Timeout time.Duration // Dial timeout
53
53
ReadTimeout time.Duration // I/O read timeout
54
54
WriteTimeout time.Duration // I/O write timeout
55
55
Logger Logger // Logger
56
56
57
+ // boolean fields
58
+
57
59
AllowAllFiles bool // Allow all files to be used with LOAD DATA LOCAL INFILE
58
60
AllowCleartextPasswords bool // Allows the cleartext client side plugin
59
61
AllowFallbackToPlaintext bool // Allows fallback to unencrypted connection if server does not support TLS
@@ -66,17 +68,48 @@ type Config struct {
66
68
MultiStatements bool // Allow multiple statements in one query
67
69
ParseTime bool // Parse time values to time.Time
68
70
RejectReadOnly bool // Reject read-only connections
71
+
72
+ // unexported fields. new options should be come here
73
+
74
+ pubKey * rsa.PublicKey // Server public key
75
+ timeTruncate time.Duration // Truncate time.Time values to the specified duration
69
76
}
70
77
78
+ // Functional Options Pattern
79
+ // https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis
80
+ type Option func (* Config ) error
81
+
71
82
// NewConfig creates a new Config and sets default values.
72
83
func NewConfig () * Config {
73
- return & Config {
84
+ cfg := & Config {
74
85
Loc : time .UTC ,
75
86
MaxAllowedPacket : defaultMaxAllowedPacket ,
76
87
Logger : defaultLogger ,
77
88
AllowNativePasswords : true ,
78
89
CheckConnLiveness : true ,
79
90
}
91
+
92
+ return cfg
93
+ }
94
+
95
+ // Apply applies the given options to the Config object.
96
+ func (c * Config ) Apply (opts ... Option ) error {
97
+ for _ , opt := range opts {
98
+ err := opt (c )
99
+ if err != nil {
100
+ return err
101
+ }
102
+ }
103
+ return nil
104
+ }
105
+
106
+ // TimeTruncate sets the time duration to truncate time.Time values in
107
+ // query parameters.
108
+ func TimeTruncate (d time.Duration ) Option {
109
+ return func (cfg * Config ) error {
110
+ cfg .timeTruncate = d
111
+ return nil
112
+ }
80
113
}
81
114
82
115
func (cfg * Config ) Clone () * Config {
@@ -263,8 +296,8 @@ func (cfg *Config) FormatDSN() string {
263
296
writeDSNParam (& buf , & hasParam , "parseTime" , "true" )
264
297
}
265
298
266
- if cfg .TimeTruncate > 0 {
267
- writeDSNParam (& buf , & hasParam , "timeTruncate" , cfg .TimeTruncate .String ())
299
+ if cfg .timeTruncate > 0 {
300
+ writeDSNParam (& buf , & hasParam , "timeTruncate" , cfg .timeTruncate .String ())
268
301
}
269
302
270
303
if cfg .ReadTimeout > 0 {
@@ -509,9 +542,9 @@ func parseDSNParams(cfg *Config, params string) (err error) {
509
542
510
543
// time.Time truncation
511
544
case "timeTruncate" :
512
- cfg .TimeTruncate , err = time .ParseDuration (value )
545
+ cfg .timeTruncate , err = time .ParseDuration (value )
513
546
if err != nil {
514
- return
547
+ return fmt . Errorf ( "invalid timeTruncate value: %v, error: %w" , value , err )
515
548
}
516
549
517
550
// I/O read Timeout
0 commit comments