Files
mysqlx/options.go
T
2026-06-06 02:09:22 +08:00

341 lines
8.1 KiB
Go

package mysqlx
import (
"errors"
"time"
mysqldriver "github.com/go-sql-driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
)
// Option configures the SDK client.
type Option func(*config)
type config struct {
DSN string
DSNConfig *mysqldriver.Config
DSNUser string
DSNPassword string
DSNNet string
DSNAddr string
DSNDBName string
DSNParams map[string]string
DSNParseTime *bool
DSNTLSConfig string
DSNLoc *time.Location
DSNCollation string
DSNTimeout time.Duration
DSNReadTimeout time.Duration
DSNWriteTimeout time.Duration
Dialector gorm.Dialector
Logger logger.Interface
NamingStrategy schema.NamingStrategy
MaxIdleConns int
MaxOpenConns int
ConnMaxIdleTime time.Duration
ConnMaxLifetime time.Duration
DisableForeignKeyConstraintWhenMigrating bool
SkipDefaultTransaction bool
DryRun bool
}
type DSN struct {
}
func defaultConfig() *config {
return &config{
Logger: logger.Default,
NamingStrategy: schema.NamingStrategy{},
MaxIdleConns: 10,
MaxOpenConns: 100,
}
}
func buildDSN(cfg *config) (string, error) {
var mysqlConfig *mysqldriver.Config
if cfg.DSN != "" {
parsed, err := mysqldriver.ParseDSN(cfg.DSN)
if err != nil {
return "", err
}
mysqlConfig = parsed
} else if cfg.DSNConfig != nil {
mysqlConfig = cfg.DSNConfig.Clone()
} else {
mysqlConfig = mysqldriver.NewConfig()
}
applyMySQLConfigOverrides(mysqlConfig, cfg)
if mysqlConfig.User == "" && mysqlConfig.Passwd == "" && mysqlConfig.Addr == "" && mysqlConfig.DBName == "" && len(mysqlConfig.Params) == 0 {
if cfg.DSN == "" {
return "", errors.New("mysqlx: DSN or expanded DSN configuration must be provided")
}
}
return mysqlConfig.FormatDSN(), nil
}
func applyMySQLConfigOverrides(mysqlConfig *mysqldriver.Config, cfg *config) {
if cfg.DSNConfig != nil {
mergeMySQLConfig(mysqlConfig, cfg.DSNConfig)
}
if cfg.DSNUser != "" {
mysqlConfig.User = cfg.DSNUser
}
if cfg.DSNPassword != "" {
mysqlConfig.Passwd = cfg.DSNPassword
}
if cfg.DSNNet != "" {
mysqlConfig.Net = cfg.DSNNet
}
if cfg.DSNAddr != "" {
mysqlConfig.Addr = cfg.DSNAddr
}
if cfg.DSNDBName != "" {
mysqlConfig.DBName = cfg.DSNDBName
}
if cfg.DSNParams != nil {
if mysqlConfig.Params == nil {
mysqlConfig.Params = map[string]string{}
}
for key, value := range cfg.DSNParams {
mysqlConfig.Params[key] = value
}
}
if cfg.DSNParseTime != nil {
mysqlConfig.ParseTime = *cfg.DSNParseTime
}
if cfg.DSNTLSConfig != "" {
mysqlConfig.TLSConfig = cfg.DSNTLSConfig
}
if cfg.DSNLoc != nil {
mysqlConfig.Loc = cfg.DSNLoc
}
if cfg.DSNCollation != "" {
mysqlConfig.Collation = cfg.DSNCollation
}
if cfg.DSNTimeout > 0 {
mysqlConfig.Timeout = cfg.DSNTimeout
}
if cfg.DSNReadTimeout > 0 {
mysqlConfig.ReadTimeout = cfg.DSNReadTimeout
}
if cfg.DSNWriteTimeout > 0 {
mysqlConfig.WriteTimeout = cfg.DSNWriteTimeout
}
}
func mergeMySQLConfig(base, override *mysqldriver.Config) {
if override.User != "" {
base.User = override.User
}
if override.Passwd != "" {
base.Passwd = override.Passwd
}
if override.Net != "" {
base.Net = override.Net
}
if override.Addr != "" {
base.Addr = override.Addr
}
if override.DBName != "" {
base.DBName = override.DBName
}
if override.Params != nil {
if base.Params == nil {
base.Params = map[string]string{}
}
for key, value := range override.Params {
base.Params[key] = value
}
}
if override.Collation != "" {
base.Collation = override.Collation
}
if override.Loc != nil {
base.Loc = override.Loc
}
if override.TLSConfig != "" {
base.TLSConfig = override.TLSConfig
}
if override.Timeout > 0 {
base.Timeout = override.Timeout
}
if override.ReadTimeout > 0 {
base.ReadTimeout = override.ReadTimeout
}
if override.WriteTimeout > 0 {
base.WriteTimeout = override.WriteTimeout
}
if override.ParseTime {
base.ParseTime = override.ParseTime
}
}
// WithDSN sets the MySQL DSN used to open the database.
func WithDSN(dsn string) Option {
return func(cfg *config) {
cfg.DSN = dsn
}
}
// WithDSNConfig sets the underlying mysql.Config used to generate the DSN.
func WithDSNConfig(mysqlConfig *mysqldriver.Config) Option {
return func(cfg *config) {
cfg.DSNConfig = mysqlConfig
}
}
// WithDSNUser sets the MySQL username.
func WithDSNUser(user string) Option {
return func(cfg *config) {
cfg.DSNUser = user
}
}
// WithDSNPassword sets the MySQL password.
func WithDSNPassword(password string) Option {
return func(cfg *config) {
cfg.DSNPassword = password
}
}
// WithDSNNet sets the network type for the DSN.
func WithDSNNet(net string) Option {
return func(cfg *config) {
cfg.DSNNet = net
}
}
// WithDSNAddr sets the database address for the DSN.
func WithDSNAddr(addr string) Option {
return func(cfg *config) {
cfg.DSNAddr = addr
}
}
// WithDSNDBName sets the database name for the DSN.
func WithDSNDBName(dbName string) Option {
return func(cfg *config) {
cfg.DSNDBName = dbName
}
}
// WithDSNParams sets additional DSN query parameters.
func WithDSNParams(params map[string]string) Option {
return func(cfg *config) {
if cfg.DSNParams == nil {
cfg.DSNParams = map[string]string{}
}
for key, value := range params {
cfg.DSNParams[key] = value
}
}
}
// WithDSNParseTime configures parseTime for the DSN.
func WithDSNParseTime(parseTime bool) Option {
return func(cfg *config) {
cfg.DSNParseTime = &parseTime
}
}
// WithDSNTLSConfig sets the TLS configuration name for the DSN.
func WithDSNTLSConfig(tlsConfig string) Option {
return func(cfg *config) {
cfg.DSNTLSConfig = tlsConfig
}
}
// WithDSNLocation sets the time location for DSN parsing.
func WithDSNLocation(loc *time.Location) Option {
return func(cfg *config) {
cfg.DSNLoc = loc
}
}
// WithDSNCollation sets the connection collation for the DSN.
func WithDSNCollation(collation string) Option {
return func(cfg *config) {
cfg.DSNCollation = collation
}
}
// WithDSNTimeout sets the dial timeout for the DSN.
func WithDSNTimeout(timeout time.Duration) Option {
return func(cfg *config) {
cfg.DSNTimeout = timeout
}
}
// WithDSNReadTimeout sets the read timeout for the DSN.
func WithDSNReadTimeout(timeout time.Duration) Option {
return func(cfg *config) {
cfg.DSNReadTimeout = timeout
}
}
// WithDSNWriteTimeout sets the write timeout for the DSN.
func WithDSNWriteTimeout(timeout time.Duration) Option {
return func(cfg *config) {
cfg.DSNWriteTimeout = timeout
}
}
// WithDialector sets a custom gorm Dialector.
func WithDialector(dialector gorm.Dialector) Option {
return func(cfg *config) {
cfg.Dialector = dialector
}
}
// WithLogger sets the gorm logger.
func WithLogger(logger logger.Interface) Option {
return func(cfg *config) {
cfg.Logger = logger
}
}
// WithNamingStrategy sets the naming strategy for gorm models.
func WithNamingStrategy(strategy schema.NamingStrategy) Option {
return func(cfg *config) {
cfg.NamingStrategy = strategy
}
}
// WithConnectionPool configures database connection pooling.
func WithConnectionPool(maxIdleConns, maxOpenConns int, maxIdleTime, maxLifetime time.Duration) Option {
return func(cfg *config) {
cfg.MaxIdleConns = maxIdleConns
cfg.MaxOpenConns = maxOpenConns
cfg.ConnMaxIdleTime = maxIdleTime
cfg.ConnMaxLifetime = maxLifetime
}
}
// WithDisableForeignKeyConstraintWhenMigrating toggles foreign key constraint creation during migrations.
func WithDisableForeignKeyConstraintWhenMigrating(disable bool) Option {
return func(cfg *config) {
cfg.DisableForeignKeyConstraintWhenMigrating = disable
}
}
// WithSkipDefaultTransaction toggles default transactions in gorm.
func WithSkipDefaultTransaction(skip bool) Option {
return func(cfg *config) {
cfg.SkipDefaultTransaction = skip
}
}
// WithDryRun toggles gorm dry run mode.
func WithDryRun(dryRun bool) Option {
return func(cfg *config) {
cfg.DryRun = dryRun
}
}