func (cfg *Config) FormatDSN() string {
	var buf bytes.Buffer
	if len(cfg.User) > 0 {
		buf.WriteString(cfg.User)
		if len(cfg.Passwd) > 0 {
			buf.WriteByte(':')
			buf.WriteString(cfg.Passwd)
		}
		buf.WriteByte('@')
	}
	if len(cfg.Net) > 0 {
		buf.WriteString(cfg.Net)
		if len(cfg.Addr) > 0 {
			buf.WriteByte('(')
			buf.WriteString(cfg.Addr)
			buf.WriteByte(')')
		}
	}
	buf.WriteByte('/')
	buf.WriteString(cfg.DBName)
	hasParam := false
	if cfg.AllowAllFiles {
		hasParam = true
		buf.WriteString("?allowAllFiles=true")
	}
	if cfg.AllowCleartextPasswords {
		if hasParam {
			buf.WriteString("&allowCleartextPasswords=true")
		} else {
			hasParam = true
			buf.WriteString("?allowCleartextPasswords=true")
		}
	}
	if cfg.AllowNativePasswords {
		if hasParam {
			buf.WriteString("&allowNativePasswords=true")
		} else {
			hasParam = true
			buf.WriteString("?allowNativePasswords=true")
		}
	}
	if cfg.AllowOldPasswords {
		if hasParam {
			buf.WriteString("&allowOldPasswords=true")
		} else {
			hasParam = true
			buf.WriteString("?allowOldPasswords=true")
		}
	}
	if cfg.ClientFoundRows {
		if hasParam {
			buf.WriteString("&clientFoundRows=true")
		} else {
			hasParam = true
			buf.WriteString("?clientFoundRows=true")
		}
	}
	if col := cfg.Collation; col != defaultCollation && len(col) > 0 {
		if hasParam {
			buf.WriteString("&collation=")
		} else {
			hasParam = true
			buf.WriteString("?collation=")
		}
		buf.WriteString(col)
	}
	if cfg.ColumnsWithAlias {
		if hasParam {
			buf.WriteString("&columnsWithAlias=true")
		} else {
			hasParam = true
			buf.WriteString("?columnsWithAlias=true")
		}
	}
	if cfg.InterpolateParams {
		if hasParam {
			buf.WriteString("&interpolateParams=true")
		} else {
			hasParam = true
			buf.WriteString("?interpolateParams=true")
		}
	}
	if cfg.Loc != time.UTC && cfg.Loc != nil {
		if hasParam {
			buf.WriteString("&loc=")
		} else {
			hasParam = true
			buf.WriteString("?loc=")
		}
		buf.WriteString(url.QueryEscape(cfg.Loc.String()))
	}
	if cfg.MultiStatements {
		if hasParam {
			buf.WriteString("&multiStatements=true")
		} else {
			hasParam = true
			buf.WriteString("?multiStatements=true")
		}
	}
	if cfg.ParseTime {
		if hasParam {
			buf.WriteString("&parseTime=true")
		} else {
			hasParam = true
			buf.WriteString("?parseTime=true")
		}
	}
	if cfg.ReadTimeout > 0 {
		if hasParam {
			buf.WriteString("&readTimeout=")
		} else {
			hasParam = true
			buf.WriteString("?readTimeout=")
		}
		buf.WriteString(cfg.ReadTimeout.String())
	}
	if cfg.Strict {
		if hasParam {
			buf.WriteString("&strict=true")
		} else {
			hasParam = true
			buf.WriteString("?strict=true")
		}
	}
	if cfg.Timeout > 0 {
		if hasParam {
			buf.WriteString("&timeout=")
		} else {
			hasParam = true
			buf.WriteString("?timeout=")
		}
		buf.WriteString(cfg.Timeout.String())
	}
	if len(cfg.TLSConfig) > 0 {
		if hasParam {
			buf.WriteString("&tls=")
		} else {
			hasParam = true
			buf.WriteString("?tls=")
		}
		buf.WriteString(url.QueryEscape(cfg.TLSConfig))
	}
	if cfg.WriteTimeout > 0 {
		if hasParam {
			buf.WriteString("&writeTimeout=")
		} else {
			hasParam = true
			buf.WriteString("?writeTimeout=")
		}
		buf.WriteString(cfg.WriteTimeout.String())
	}
	if cfg.MaxAllowedPacket > 0 {
		if hasParam {
			buf.WriteString("&maxAllowedPacket=")
		} else {
			hasParam = true
			buf.WriteString("?maxAllowedPacket=")
		}
		buf.WriteString(strconv.Itoa(cfg.MaxAllowedPacket))
	}
	if cfg.Params != nil {
		for param, value := range cfg.Params {
			if hasParam {
				buf.WriteByte('&')
			} else {
				hasParam = true
				buf.WriteByte('?')
			}
			buf.WriteString(param)
			buf.WriteByte('=')
			buf.WriteString(url.QueryEscape(value))
		}
	}
	return buf.String()
}
FormatDSN formats the given Config into a DSN string which can be passed to
the driver.
package mysql
import (
	"bytes"
	"crypto/tls"
	"errors"
	"fmt"
	"net"
	"net/url"
	"strconv"
	"strings"
	"time"
)
var (
	errInvalidDSNUnescaped       = errors.New("invalid DSN: did you forget to escape a param value?")
	errInvalidDSNAddr            = errors.New("invalid DSN: network address not terminated (missing closing brace)")
	errInvalidDSNNoSlash         = errors.New("invalid DSN: missing the slash separating the database name")
	errInvalidDSNUnsafeCollation = errors.New("invalid DSN: interpolateParams can not be used with unsafe collations")
)
type Config struct {
	User             string             
	Passwd           string             
	Net              string             
	Addr             string             
	DBName           string             
	Params           map[string]string  
	Collation        string             
	Loc              *time.Location     
	MaxAllowedPacket int                
	TLSConfig        string             
	tls              *tls.Config        
	Timeout          time.Duration      
	ReadTimeout      time.Duration      
	WriteTimeout     time.Duration      
	AllowAllFiles           bool  
	AllowCleartextPasswords bool  
	AllowNativePasswords    bool  
	AllowOldPasswords       bool  
	ClientFoundRows         bool  
	ColumnsWithAlias        bool  
	InterpolateParams       bool  
	MultiStatements         bool  
	ParseTime               bool  
	Strict                  bool  
}