feat: optional MySQL/MariaDB database driver for deployments that cannot use local SQLite
This commit is contained in:
1 parent
81e299f09a
commit
d752a61e52
35 files changed
+2896
-76
No files matched your search
@@ -0,0 +1,86 @@
|
||||
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
|
||||
}
|
||||
Reference in new issue
Block a user