package database import ( domainUpdate "RenewCMS/internal/domain/update" "fmt" "net" "strings" "time" mysqldriver "github.com/go-sql-driver/mysql" "gorm.io/driver/mysql" "gorm.io/gorm" ) const ( DriverMySQL = "mysql" mysqlCharset = "utf8mb4" mysqlLocation = "UTC" mysqlCollation = "utf8mb4_bin" mysqlConnectTimeout = 5 * time.Second mysqlSessionSQLMode = "'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'" mysqlTableOptionsKey = "gorm:table_options" redactedPassword = "***" ) type mysqlDriver struct{} type MySQLConfig struct { Host string Port string User string Password string Name string TLS string } func MySQLDSN(config MySQLConfig) string { dsn := mysqldriver.NewConfig() dsn.User = config.User dsn.Passwd = config.Password dsn.Net = "tcp" dsn.Addr = net.JoinHostPort(config.Host, config.Port) dsn.DBName = config.Name dsn.TLSConfig = config.TLS dsn.ParseTime = true dsn.ClientFoundRows = true dsn.Collation = mysqlCollation dsn.Timeout = mysqlConnectTimeout dsn.Params = map[string]string{ "charset": mysqlCharset, "loc": mysqlLocation, "sql_mode": mysqlSessionSQLMode, } return dsn.FormatDSN() } func (mysqlDriver) Open(source string) (*gorm.DB, error) { parsed, err := mysqldriver.ParseDSN(source) if err != nil { return nil, fmt.Errorf("the mysql connection settings are invalid") } db, err := gorm.Open(mysql.Open(source), &gorm.Config{}) if err != nil { return nil, fmt.Errorf("cannot use the mysql server at %s: %s", parsed.Addr, redact(err.Error(), parsed.Passwd)) } return db, nil } func (mysqlDriver) NewBackup(db *gorm.DB, directory string, now func() time.Time) domainUpdate.DatabaseBackup { return NewMySQLBackup(db, directory, now) } func redact(message string, secret string) string { if secret == "" { return message } return strings.ReplaceAll(message, secret, redactedPassword) } func tableOptionsFor(db *gorm.DB) *gorm.DB { if db.Dialector.Name() == DriverMySQL { return db.Set(mysqlTableOptionsKey, "DEFAULT CHARSET="+mysqlCharset+" COLLATE="+mysqlCollation) } return db }