package mysql import ( "fmt" "net/url" ) // Config holds MySQL connection settings. Required fields must be supplied // by the caller; optional fields have production-safe defaults via [DefaultConfig]. // // Note on Collation: go-sql-driver v1.8.x negotiates the connection collation // via a 1-byte handshake ID (max 255). MariaDB 11.4+ collations such as // utf8mb4_uca1400_as_cs carry IDs > 255 and cannot be set through the DSN // collation parameter. Set the desired collation at the database/table level // in your schema migrations instead. type Config struct { Host string `env:"EINHERJAR_MYSQL_HOST,required"` Port int `env:"EINHERJAR_MYSQL_PORT" envDefault:"3306"` User string `env:"EINHERJAR_MYSQL_USER,required"` Password string `env:"EINHERJAR_MYSQL_PASSWORD,required"` Name string `env:"EINHERJAR_MYSQL_NAME,required"` MaxConns int `env:"EINHERJAR_MYSQL_MAX_CONNS" envDefault:"5"` MinConns int `env:"EINHERJAR_MYSQL_MIN_CONNS" envDefault:"2"` MaxConnLifetime string `env:"EINHERJAR_MYSQL_MAX_CONN_LIFETIME" envDefault:"1h"` MaxConnIdleTime string `env:"EINHERJAR_MYSQL_MAX_CONN_IDLE_TIME" envDefault:"30m"` // Charset is the connection character set. Defaults to "utf8mb4". Charset string `env:"EINHERJAR_MYSQL_CHARSET" envDefault:"utf8mb4"` // Loc is the IANA timezone name for time.Time ↔ MySQL DATETIME conversion. Defaults to "UTC". Loc string `env:"EINHERJAR_MYSQL_LOC" envDefault:"UTC"` // ParseTime controls whether DATE/DATETIME columns are mapped to time.Time. Defaults to "true". ParseTime string `env:"EINHERJAR_MYSQL_PARSE_TIME" envDefault:"true"` } // DefaultConfig returns a Config with all optional fields set to production-safe defaults. // Callers must supply Host, Port, User, Password, and Name. func DefaultConfig() Config { return Config{ Port: 3306, MaxConns: 5, MinConns: 2, MaxConnLifetime: "1h", MaxConnIdleTime: "30m", Charset: "utf8mb4", Loc: "UTC", ParseTime: "true", } } // DSN constructs a MySQL DSN from the configuration. func (c Config) DSN() string { charset := c.Charset if charset == "" { charset = "utf8mb4" } loc := c.Loc if loc == "" { loc = "UTC" } parseTime := c.ParseTime if parseTime == "" { parseTime = "true" } q := url.Values{} q.Set("charset", charset) q.Set("loc", loc) q.Set("parseTime", parseTime) return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?%s", c.User, c.Password, c.Host, c.Port, c.Name, q.Encode()) }