108 lines
2.8 KiB
Go
108 lines
2.8 KiB
Go
package component
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"gitea.party/public-messag-service/config"
|
|
"github.com/urfave/cli/v2"
|
|
"gorm.io/driver/mysql"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/schema"
|
|
"gorm.io/plugin/dbresolver"
|
|
"strings"
|
|
)
|
|
|
|
type MySQLClient struct {
|
|
DB *gorm.DB
|
|
Cfg config.EntityMysql
|
|
ref *MySQL
|
|
}
|
|
|
|
func (c *MySQLClient) Ref() *MySQL {
|
|
return c.ref
|
|
}
|
|
|
|
func (c *MySQLClient) CliFlags(name string) []cli.Flag {
|
|
return []cli.Flag{
|
|
&cli.IntFlag{
|
|
Name: fmt.Sprintf("mysql-%s-open-limit", name),
|
|
Usage: fmt.Sprintf("mysql(%s) max open limit", name),
|
|
Action: func(_ *cli.Context, v int) error { c.Cfg.MaxOpen = v; return nil },
|
|
},
|
|
&cli.IntFlag{
|
|
Name: fmt.Sprintf("mysql-%s-idle-limit", name),
|
|
Usage: fmt.Sprintf("mysql(%s) idle open limit", name),
|
|
Action: func(_ *cli.Context, v int) error { c.Cfg.MaxIdle = v; return nil },
|
|
},
|
|
&cli.StringFlag{
|
|
Name: fmt.Sprintf("mysql-%s-dsn", name),
|
|
Usage: fmt.Sprintf("mysql(%s) DSN (format: `{{user_name}}:{{password}}@tcp({{host}}:{{port}})/{{db_name}}?{{connect_options}}`)", name),
|
|
Action: func(_ *cli.Context, val string) (err error) {
|
|
dsn := strings.Split(val, ";")
|
|
if err = c.Cfg.Master.ParserDSN(dsn[0]); err == nil {
|
|
if len(dsn) > 1 {
|
|
c.Cfg.Slave = make([]config.ConnectMysql, 0, len(dsn)-1)
|
|
for i, l := 1, len(dsn); i < l; i++ {
|
|
v := config.ConnectMysql{}
|
|
if err = v.ParserDSN(dsn[i]); err != nil {
|
|
break
|
|
}
|
|
c.Cfg.Slave = append(c.Cfg.Slave, v)
|
|
}
|
|
}
|
|
}
|
|
if err != nil {
|
|
err = fmt.Errorf("Mysql DSN is invalid(%s)", err.Error())
|
|
}
|
|
return err
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func (c *MySQLClient) Init(env int, cc *MySQL) {
|
|
c.ref = cc
|
|
}
|
|
|
|
func (c *MySQLClient) Config() *config.EntityMysql {
|
|
return &c.Cfg
|
|
}
|
|
|
|
func (c *MySQLClient) Load(name string) (err error) {
|
|
mastDB := mysql.Open(c.Cfg.Master.GetConnectDSN())
|
|
gormDB, err := gorm.Open(mastDB, &gorm.Config{
|
|
SkipDefaultTransaction: true,
|
|
Logger: &c.ref.Log,
|
|
NamingStrategy: schema.NamingStrategy{
|
|
SingularTable: true,
|
|
},
|
|
})
|
|
if err == nil {
|
|
if len(c.Cfg.Slave) > 0 {
|
|
slaveDBs := make([]gorm.Dialector, 0, len(c.Cfg.Slave))
|
|
for k := range c.Cfg.Slave {
|
|
slaveDBs = append(slaveDBs, mysql.Open(c.Cfg.Slave[k].GetConnectDSN()))
|
|
}
|
|
readWritePlugin := dbresolver.Register(dbresolver.Config{
|
|
Sources: []gorm.Dialector{mastDB},
|
|
Replicas: slaveDBs,
|
|
Policy: dbresolver.RandomPolicy{},
|
|
})
|
|
readWritePlugin.SetMaxOpenConns(c.Cfg.MaxOpen)
|
|
readWritePlugin.SetMaxIdleConns(c.Cfg.MaxIdle)
|
|
err = gormDB.Use(readWritePlugin)
|
|
} else {
|
|
var sqlDB *sql.DB
|
|
if sqlDB, err = gormDB.DB(); err == nil {
|
|
sqlDB.SetMaxOpenConns(c.Cfg.MaxOpen)
|
|
sqlDB.SetMaxIdleConns(c.Cfg.MaxIdle)
|
|
}
|
|
}
|
|
}
|
|
if err != nil {
|
|
gormDB, err = nil, fmt.Errorf("Load Mysql (%s) Failed (Error: %s) ", name, err.Error())
|
|
}
|
|
c.DB = gormDB
|
|
return err
|
|
}
|