Files
lone-services/pkg/mysql/mysql.go
T
gjs be8f89f449
CI / changes (push) Successful in 5s
CI / docker-bff (push) Failing after 7s
CI / docker-product (push) Failing after 5s
CI / docker-admin (push) Failing after 4s
CI / docker-user (push) Failing after 6s
change layout
2026-08-20 15:41:44 +08:00

94 lines
2.0 KiB
Go

package mysql
import (
"fmt"
"lone-services/pkg/utils"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/schema"
"gorm.io/plugin/dbresolver"
)
type Config struct {
Host string
Port int
User string
Password string
Database string
Charset string
Prefix string
ReadHost string
ReadPort int
ReadUser string
ReadPassword string
ReadDatabase string
}
func New(c Config) (*gorm.DB, error) {
dsn := buildDSN(c.User, c.Password, c.Host, c.Port, c.Database, c.Charset)
db, err := gorm.Open(mysql.New(mysql.Config{
DSN: dsn,
DefaultStringSize: 256,
DisableDatetimePrecision: true,
DontSupportRenameIndex: true,
DontSupportRenameColumn: true,
SkipInitializeWithVersion: false,
}), &gorm.Config{
NamingStrategy: schema.NamingStrategy{
TablePrefix: c.Prefix,
},
})
if err != nil {
return nil, fmt.Errorf("mysql open: %w", err)
}
readDSN := buildReadDSN(c)
if readDSN != "" {
if err := db.Use(dbresolver.Register(dbresolver.Config{
Sources: []gorm.Dialector{mysql.Open(dsn)},
Replicas: []gorm.Dialector{mysql.Open(readDSN)},
Policy: dbresolver.RandomPolicy{},
})); err != nil {
return nil, fmt.Errorf("mysql dbresolver: %w", err)
}
}
return db, nil
}
func buildReadDSN(c Config) string {
if c.ReadHost == utils.StringEmpty {
return utils.StringEmpty
}
port := c.ReadPort
if port == utils.NumberZero {
port = c.Port
}
user := c.ReadUser
if user == utils.StringEmpty {
user = c.User
}
password := c.ReadPassword
if password == utils.StringEmpty {
password = c.Password
}
database := c.ReadDatabase
if database == utils.StringEmpty {
database = c.Database
}
charset := c.Charset
if charset == utils.StringEmpty {
charset = "utf8mb4"
}
return buildDSN(user, password, c.ReadHost, port, database, charset)
}
func buildDSN(user, password, host string, port int, database, charset string) string {
return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=True&loc=Local",
user, password, host, port, database, charset)
}