Skip to content

add Charset() option #1679

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 10, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion dsn.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ type Config struct {
DBName string // Database name
Params map[string]string // Connection parameters
ConnectionAttributes string // Connection Attributes, comma-delimited string of user-defined "key:value" pairs
charsets []string // Connection charset. When set, this will be set in SET NAMES <charset> query
Collation string // Connection collation. When set, this will be set in SET NAMES <charset> COLLATE <collation> query
Loc *time.Location // Location for time.Time values
MaxAllowedPacket int // Max packet size allowed
Expand Down Expand Up @@ -81,6 +80,7 @@ type Config struct {
beforeConnect func(context.Context, *Config) error // Invoked before a connection is established
pubKey *rsa.PublicKey // Server public key
timeTruncate time.Duration // Truncate time.Time values to the specified duration
charsets []string // Connection charset. When set, this will be set in SET NAMES <charset> query
}

// Functional Options Pattern
Expand Down Expand Up @@ -135,6 +135,21 @@ func EnableCompression(yes bool) Option {
}
}

// Charset sets the connection charset and collation.
//
// charset is the connection charset.
// collation is the connection collation. It can be null or empty string.
//
// When collation is not specified, `SET NAMES <charset>` command is sent when the connection is established.
// When collation is specified, `SET NAMES <charset> COLLATE <collation>` command is sent when the connection is established.
func Charset(charset, collation string) Option {
return func(cfg *Config) error {
cfg.charsets = []string{charset}
cfg.Collation = collation
return nil
}
}
Comment on lines +138 to +151
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add validation for charset parameter.

The function accepts any string as charset without validation. Consider adding validation to ensure the charset is supported by MySQL to prevent runtime errors.

 func Charset(charset, collation string) Option {
 	return func(cfg *Config) error {
+		if charset == "" {
+			return errors.New("charset cannot be empty")
+		}
 		cfg.charsets = []string{charset}
 		cfg.Collation = collation
 		return nil
 	}
 }

Additionally, you might want to consider maintaining a list of valid MySQL charsets for validation:

var validCharsets = map[string]bool{
    "utf8mb4": true,
    "utf8": true,
    "latin1": true,
    // Add other supported charsets
}

func Charset(charset, collation string) Option {
    return func(cfg *Config) error {
        if charset == "" {
            return errors.New("charset cannot be empty")
        }
        if !validCharsets[charset] {
            return fmt.Errorf("unsupported charset: %s", charset)
        }
        cfg.charsets = []string{charset}
        cfg.Collation = collation
        return nil
    }
}


func (cfg *Config) Clone() *Config {
cp := *cfg
if cp.TLS != nil {
Expand Down