first commit
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"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 == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
port := c.ReadPort
|
||||
if port == 0 {
|
||||
port = c.Port
|
||||
}
|
||||
user := c.ReadUser
|
||||
if user == "" {
|
||||
user = c.User
|
||||
}
|
||||
password := c.ReadPassword
|
||||
if password == "" {
|
||||
password = c.Password
|
||||
}
|
||||
database := c.ReadDatabase
|
||||
if database == "" {
|
||||
database = c.Database
|
||||
}
|
||||
charset := c.Charset
|
||||
if charset == "" {
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user