初始化实现
This commit is contained in:
@@ -0,0 +1,31 @@
|
|||||||
|
# mysqlx Examples
|
||||||
|
|
||||||
|
本目录提供了 `mysqlx` SDK 的多种配置使用示例,按场景拆分到独立子目录:
|
||||||
|
|
||||||
|
- `basic_dsn/`:通过原始 DSN 字符串创建客户端。
|
||||||
|
- `expanded_dsn/`:通过 `WithDSNConfig` 及单个字段展开设置连接信息。
|
||||||
|
- `custom_dialector/`:使用自定义 `gorm.Dialector`(例如 SQLite 内存数据库)创建客户端。
|
||||||
|
- `advanced_options/`:演示 GORM 高级配置与连接池选项,如 `NamingStrategy`、`SkipDefaultTransaction`、`DisableForeignKeyConstraintWhenMigrating` 等。
|
||||||
|
|
||||||
|
## 运行示例
|
||||||
|
|
||||||
|
示例目录下每个文件可单独执行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd c:/Code/pkg/mysqlx
|
||||||
|
go run ./example/basic_dsn/basic_dsn.go
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go run ./example/expanded_dsn/expanded_dsn.go
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go run ./example/custom_dialector/custom_dialector.go
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go run ./example/advanced_options/gorm_advanced_options.go
|
||||||
|
```
|
||||||
|
|
||||||
|
也可以运行整个 `example` 目录里的单个子目录或文件。
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"code.yun.ink/pkg/mysqlx"
|
||||||
|
"gorm.io/gorm/logger"
|
||||||
|
"gorm.io/gorm/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
client, err := mysqlx.NewDB(
|
||||||
|
mysqlx.WithDSN("user:password@tcp(127.0.0.1:3306)/testdb?parseTime=true&loc=Local"),
|
||||||
|
mysqlx.WithLogger(logger.Default.LogMode(logger.Info)),
|
||||||
|
mysqlx.WithNamingStrategy(schema.NamingStrategy{SingularTable: true}),
|
||||||
|
mysqlx.WithDisableForeignKeyConstraintWhenMigrating(true),
|
||||||
|
mysqlx.WithSkipDefaultTransaction(true),
|
||||||
|
mysqlx.WithConnectionPool(5, 20, 15*time.Minute, time.Hour),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to create mysqlx client: %v", err)
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
fmt.Println("MySQL client created with advanced GORM and connection pool options")
|
||||||
|
_ = client
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"code.yun.ink/pkg/mysqlx"
|
||||||
|
"gorm.io/gorm/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
client, err := mysqlx.NewDB(
|
||||||
|
mysqlx.WithDSN("user:password@tcp(127.0.0.1:3306)/testdb?parseTime=true&loc=Local"),
|
||||||
|
mysqlx.WithLogger(logger.Default.LogMode(logger.Info)),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to create mysqlx client: %v", err)
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
fmt.Println("MySQL client created with raw DSN")
|
||||||
|
_ = client
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"code.yun.ink/pkg/mysqlx"
|
||||||
|
"gorm.io/driver/sqlite"
|
||||||
|
"gorm.io/gorm/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
client, err := mysqlx.NewDB(
|
||||||
|
mysqlx.WithDialector(sqlite.Open("file::memory:?cache=shared")),
|
||||||
|
mysqlx.WithLogger(logger.Default.LogMode(logger.Info)),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to create mysqlx client with custom dialector: %v", err)
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
fmt.Println("MySQL SDK client created with custom Dialector")
|
||||||
|
_ = client
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"code.yun.ink/pkg/mysqlx"
|
||||||
|
"github.com/go-sql-driver/mysql"
|
||||||
|
"gorm.io/gorm/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cfg := mysql.NewConfig()
|
||||||
|
cfg.User = "testuser"
|
||||||
|
cfg.Passwd = "password"
|
||||||
|
cfg.Net = "tcp"
|
||||||
|
cfg.Addr = "127.0.0.1:3306"
|
||||||
|
cfg.DBName = "testdb"
|
||||||
|
cfg.ParseTime = true
|
||||||
|
cfg.Loc = time.Local
|
||||||
|
cfg.Params = map[string]string{
|
||||||
|
"charset": "utf8mb4",
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := mysqlx.NewDB(
|
||||||
|
mysqlx.WithDSNConfig(cfg),
|
||||||
|
mysqlx.WithDSNTimeout(5*time.Second),
|
||||||
|
mysqlx.WithDSNReadTimeout(10*time.Second),
|
||||||
|
mysqlx.WithDSNWriteTimeout(10*time.Second),
|
||||||
|
mysqlx.WithDSNParams(map[string]string{"multiStatements": "true"}),
|
||||||
|
mysqlx.WithLogger(logger.Default.LogMode(logger.Warn)),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to create mysqlx client: %v", err)
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
fmt.Println("MySQL client created with expanded DSN configuration")
|
||||||
|
_ = client
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
module code.yun.ink/pkg/mysqlx
|
||||||
|
|
||||||
|
go 1.26.3
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/DATA-DOG/go-sqlmock v1.5.2
|
||||||
|
github.com/go-sql-driver/mysql v1.8.1
|
||||||
|
gorm.io/driver/mysql v1.6.0
|
||||||
|
gorm.io/driver/sqlite v1.6.0
|
||||||
|
gorm.io/gorm v1.31.1
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.22 // indirect
|
||||||
|
golang.org/x/text v0.20.0 // indirect
|
||||||
|
)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
|
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
|
||||||
|
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
|
||||||
|
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||||
|
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||||
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
|
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
|
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
|
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||||
|
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||||
|
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||||
|
gorm.io/driver/mysql v1.6.0 h1:eNbLmNTpPpTOVZi8MMxCi2aaIm0ZpInbORNXDwyLGvg=
|
||||||
|
gorm.io/driver/mysql v1.6.0/go.mod h1:D/oCC2GWK3M/dqoLxnOlaNKmXz8WNTfcS9y5ovaSqKo=
|
||||||
|
gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ=
|
||||||
|
gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
|
||||||
|
gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg=
|
||||||
|
gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package mysqlx
|
||||||
|
|
||||||
|
import (
|
||||||
|
drivermysql "gorm.io/driver/mysql"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Client is the wrapper around a gorm DB instance.
|
||||||
|
type Client struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a Client using functional options.
|
||||||
|
// It requires either a DSN or a custom gorm Dialector.
|
||||||
|
func NewDB(opts ...Option) (*Client, error) {
|
||||||
|
cfg := defaultConfig()
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.Dialector == nil {
|
||||||
|
dsn, err := buildDSN(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cfg.Dialector = drivermysql.Open(dsn)
|
||||||
|
}
|
||||||
|
|
||||||
|
gormConfig := &gorm.Config{
|
||||||
|
Logger: cfg.Logger,
|
||||||
|
NamingStrategy: cfg.NamingStrategy,
|
||||||
|
DisableForeignKeyConstraintWhenMigrating: cfg.DisableForeignKeyConstraintWhenMigrating,
|
||||||
|
SkipDefaultTransaction: cfg.SkipDefaultTransaction,
|
||||||
|
DryRun: cfg.DryRun,
|
||||||
|
}
|
||||||
|
|
||||||
|
db, err := gorm.Open(cfg.Dialector, gormConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlDB, err := db.DB()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.MaxIdleConns > 0 {
|
||||||
|
sqlDB.SetMaxIdleConns(cfg.MaxIdleConns)
|
||||||
|
}
|
||||||
|
if cfg.MaxOpenConns > 0 {
|
||||||
|
sqlDB.SetMaxOpenConns(cfg.MaxOpenConns)
|
||||||
|
}
|
||||||
|
if cfg.ConnMaxIdleTime > 0 {
|
||||||
|
sqlDB.SetConnMaxIdleTime(cfg.ConnMaxIdleTime)
|
||||||
|
}
|
||||||
|
if cfg.ConnMaxLifetime > 0 {
|
||||||
|
sqlDB.SetConnMaxLifetime(cfg.ConnMaxLifetime)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Client{db: db}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DB returns the underlying gorm DB.
|
||||||
|
func (c *Client) DB() *gorm.DB {
|
||||||
|
return c.db
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes the underlying sql.DB connection pool.
|
||||||
|
func (c *Client) Close() error {
|
||||||
|
sqlDB, err := c.db.DB()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return sqlDB.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AutoMigrate runs gorm AutoMigrate for the provided models.
|
||||||
|
func (c *Client) AutoMigrate(models ...interface{}) error {
|
||||||
|
return c.db.AutoMigrate(models...)
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package mysqlx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/DATA-DOG/go-sqlmock"
|
||||||
|
drivermysql "gorm.io/driver/mysql"
|
||||||
|
"gorm.io/gorm/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
type testModel struct {
|
||||||
|
ID uint `gorm:"primaryKey"`
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewWithCustomDialector(t *testing.T) {
|
||||||
|
sqlDB, _, err := sqlmock.New()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create sqlmock: %v", err)
|
||||||
|
}
|
||||||
|
defer sqlDB.Close()
|
||||||
|
|
||||||
|
client, err := NewDB(
|
||||||
|
WithDialector(drivermysql.New(drivermysql.Config{Conn: sqlDB})),
|
||||||
|
WithLogger(logger.Default.LogMode(logger.Silent)),
|
||||||
|
WithConnectionPool(2, 5, 5*time.Minute, 10*time.Minute),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
if client.DB() == nil {
|
||||||
|
t.Fatal("expected non-nil DB")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuildDSNWithExpandedConfig(t *testing.T) {
|
||||||
|
cfg := defaultConfig()
|
||||||
|
WithDSNUser("testuser")(cfg)
|
||||||
|
WithDSNPassword("password")(cfg)
|
||||||
|
WithDSNNet("tcp")(cfg)
|
||||||
|
WithDSNAddr("127.0.0.1:3306")(cfg)
|
||||||
|
WithDSNDBName("testdb")(cfg)
|
||||||
|
WithDSNParams(map[string]string{"parseTime": "true", "loc": "Local"})(cfg)
|
||||||
|
WithDSNTLSConfig("false")(cfg)
|
||||||
|
dsn, err := buildDSN(cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("buildDSN returned error: %v", err)
|
||||||
|
}
|
||||||
|
if dsn == "" {
|
||||||
|
t.Fatal("expected non-empty DSN")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewWithoutDSNOrDialector(t *testing.T) {
|
||||||
|
_, err := NewDB()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected error when DSN and Dialector are missing")
|
||||||
|
}
|
||||||
|
}
|
||||||
+340
@@ -0,0 +1,340 @@
|
|||||||
|
package mysqlx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
mysqldriver "github.com/go-sql-driver/mysql"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/logger"
|
||||||
|
"gorm.io/gorm/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Option configures the SDK client.
|
||||||
|
type Option func(*config)
|
||||||
|
|
||||||
|
type config struct {
|
||||||
|
DSN string
|
||||||
|
DSNConfig *mysqldriver.Config
|
||||||
|
DSNUser string
|
||||||
|
DSNPassword string
|
||||||
|
DSNNet string
|
||||||
|
DSNAddr string
|
||||||
|
DSNDBName string
|
||||||
|
DSNParams map[string]string
|
||||||
|
DSNParseTime *bool
|
||||||
|
DSNTLSConfig string
|
||||||
|
DSNLoc *time.Location
|
||||||
|
DSNCollation string
|
||||||
|
DSNTimeout time.Duration
|
||||||
|
DSNReadTimeout time.Duration
|
||||||
|
DSNWriteTimeout time.Duration
|
||||||
|
|
||||||
|
Dialector gorm.Dialector
|
||||||
|
Logger logger.Interface
|
||||||
|
NamingStrategy schema.NamingStrategy
|
||||||
|
MaxIdleConns int
|
||||||
|
MaxOpenConns int
|
||||||
|
ConnMaxIdleTime time.Duration
|
||||||
|
ConnMaxLifetime time.Duration
|
||||||
|
DisableForeignKeyConstraintWhenMigrating bool
|
||||||
|
SkipDefaultTransaction bool
|
||||||
|
DryRun bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type DSN struct {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func defaultConfig() *config {
|
||||||
|
return &config{
|
||||||
|
Logger: logger.Default,
|
||||||
|
NamingStrategy: schema.NamingStrategy{},
|
||||||
|
MaxIdleConns: 10,
|
||||||
|
MaxOpenConns: 100,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildDSN(cfg *config) (string, error) {
|
||||||
|
var mysqlConfig *mysqldriver.Config
|
||||||
|
if cfg.DSN != "" {
|
||||||
|
parsed, err := mysqldriver.ParseDSN(cfg.DSN)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
mysqlConfig = parsed
|
||||||
|
} else if cfg.DSNConfig != nil {
|
||||||
|
mysqlConfig = cfg.DSNConfig.Clone()
|
||||||
|
} else {
|
||||||
|
mysqlConfig = mysqldriver.NewConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
applyMySQLConfigOverrides(mysqlConfig, cfg)
|
||||||
|
|
||||||
|
if mysqlConfig.User == "" && mysqlConfig.Passwd == "" && mysqlConfig.Addr == "" && mysqlConfig.DBName == "" && len(mysqlConfig.Params) == 0 {
|
||||||
|
if cfg.DSN == "" {
|
||||||
|
return "", errors.New("mysqlx: DSN or expanded DSN configuration must be provided")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mysqlConfig.FormatDSN(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func applyMySQLConfigOverrides(mysqlConfig *mysqldriver.Config, cfg *config) {
|
||||||
|
if cfg.DSNConfig != nil {
|
||||||
|
mergeMySQLConfig(mysqlConfig, cfg.DSNConfig)
|
||||||
|
}
|
||||||
|
if cfg.DSNUser != "" {
|
||||||
|
mysqlConfig.User = cfg.DSNUser
|
||||||
|
}
|
||||||
|
if cfg.DSNPassword != "" {
|
||||||
|
mysqlConfig.Passwd = cfg.DSNPassword
|
||||||
|
}
|
||||||
|
if cfg.DSNNet != "" {
|
||||||
|
mysqlConfig.Net = cfg.DSNNet
|
||||||
|
}
|
||||||
|
if cfg.DSNAddr != "" {
|
||||||
|
mysqlConfig.Addr = cfg.DSNAddr
|
||||||
|
}
|
||||||
|
if cfg.DSNDBName != "" {
|
||||||
|
mysqlConfig.DBName = cfg.DSNDBName
|
||||||
|
}
|
||||||
|
if cfg.DSNParams != nil {
|
||||||
|
if mysqlConfig.Params == nil {
|
||||||
|
mysqlConfig.Params = map[string]string{}
|
||||||
|
}
|
||||||
|
for key, value := range cfg.DSNParams {
|
||||||
|
mysqlConfig.Params[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if cfg.DSNParseTime != nil {
|
||||||
|
mysqlConfig.ParseTime = *cfg.DSNParseTime
|
||||||
|
}
|
||||||
|
if cfg.DSNTLSConfig != "" {
|
||||||
|
mysqlConfig.TLSConfig = cfg.DSNTLSConfig
|
||||||
|
}
|
||||||
|
if cfg.DSNLoc != nil {
|
||||||
|
mysqlConfig.Loc = cfg.DSNLoc
|
||||||
|
}
|
||||||
|
if cfg.DSNCollation != "" {
|
||||||
|
mysqlConfig.Collation = cfg.DSNCollation
|
||||||
|
}
|
||||||
|
if cfg.DSNTimeout > 0 {
|
||||||
|
mysqlConfig.Timeout = cfg.DSNTimeout
|
||||||
|
}
|
||||||
|
if cfg.DSNReadTimeout > 0 {
|
||||||
|
mysqlConfig.ReadTimeout = cfg.DSNReadTimeout
|
||||||
|
}
|
||||||
|
if cfg.DSNWriteTimeout > 0 {
|
||||||
|
mysqlConfig.WriteTimeout = cfg.DSNWriteTimeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mergeMySQLConfig(base, override *mysqldriver.Config) {
|
||||||
|
if override.User != "" {
|
||||||
|
base.User = override.User
|
||||||
|
}
|
||||||
|
if override.Passwd != "" {
|
||||||
|
base.Passwd = override.Passwd
|
||||||
|
}
|
||||||
|
if override.Net != "" {
|
||||||
|
base.Net = override.Net
|
||||||
|
}
|
||||||
|
if override.Addr != "" {
|
||||||
|
base.Addr = override.Addr
|
||||||
|
}
|
||||||
|
if override.DBName != "" {
|
||||||
|
base.DBName = override.DBName
|
||||||
|
}
|
||||||
|
if override.Params != nil {
|
||||||
|
if base.Params == nil {
|
||||||
|
base.Params = map[string]string{}
|
||||||
|
}
|
||||||
|
for key, value := range override.Params {
|
||||||
|
base.Params[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if override.Collation != "" {
|
||||||
|
base.Collation = override.Collation
|
||||||
|
}
|
||||||
|
if override.Loc != nil {
|
||||||
|
base.Loc = override.Loc
|
||||||
|
}
|
||||||
|
if override.TLSConfig != "" {
|
||||||
|
base.TLSConfig = override.TLSConfig
|
||||||
|
}
|
||||||
|
if override.Timeout > 0 {
|
||||||
|
base.Timeout = override.Timeout
|
||||||
|
}
|
||||||
|
if override.ReadTimeout > 0 {
|
||||||
|
base.ReadTimeout = override.ReadTimeout
|
||||||
|
}
|
||||||
|
if override.WriteTimeout > 0 {
|
||||||
|
base.WriteTimeout = override.WriteTimeout
|
||||||
|
}
|
||||||
|
if override.ParseTime {
|
||||||
|
base.ParseTime = override.ParseTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDSN sets the MySQL DSN used to open the database.
|
||||||
|
func WithDSN(dsn string) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DSN = dsn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDSNConfig sets the underlying mysql.Config used to generate the DSN.
|
||||||
|
func WithDSNConfig(mysqlConfig *mysqldriver.Config) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DSNConfig = mysqlConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDSNUser sets the MySQL username.
|
||||||
|
func WithDSNUser(user string) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DSNUser = user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDSNPassword sets the MySQL password.
|
||||||
|
func WithDSNPassword(password string) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DSNPassword = password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDSNNet sets the network type for the DSN.
|
||||||
|
func WithDSNNet(net string) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DSNNet = net
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDSNAddr sets the database address for the DSN.
|
||||||
|
func WithDSNAddr(addr string) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DSNAddr = addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDSNDBName sets the database name for the DSN.
|
||||||
|
func WithDSNDBName(dbName string) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DSNDBName = dbName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDSNParams sets additional DSN query parameters.
|
||||||
|
func WithDSNParams(params map[string]string) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
if cfg.DSNParams == nil {
|
||||||
|
cfg.DSNParams = map[string]string{}
|
||||||
|
}
|
||||||
|
for key, value := range params {
|
||||||
|
cfg.DSNParams[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDSNParseTime configures parseTime for the DSN.
|
||||||
|
func WithDSNParseTime(parseTime bool) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DSNParseTime = &parseTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDSNTLSConfig sets the TLS configuration name for the DSN.
|
||||||
|
func WithDSNTLSConfig(tlsConfig string) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DSNTLSConfig = tlsConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDSNLocation sets the time location for DSN parsing.
|
||||||
|
func WithDSNLocation(loc *time.Location) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DSNLoc = loc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDSNCollation sets the connection collation for the DSN.
|
||||||
|
func WithDSNCollation(collation string) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DSNCollation = collation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDSNTimeout sets the dial timeout for the DSN.
|
||||||
|
func WithDSNTimeout(timeout time.Duration) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DSNTimeout = timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDSNReadTimeout sets the read timeout for the DSN.
|
||||||
|
func WithDSNReadTimeout(timeout time.Duration) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DSNReadTimeout = timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDSNWriteTimeout sets the write timeout for the DSN.
|
||||||
|
func WithDSNWriteTimeout(timeout time.Duration) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DSNWriteTimeout = timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDialector sets a custom gorm Dialector.
|
||||||
|
func WithDialector(dialector gorm.Dialector) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.Dialector = dialector
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithLogger sets the gorm logger.
|
||||||
|
func WithLogger(logger logger.Interface) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.Logger = logger
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithNamingStrategy sets the naming strategy for gorm models.
|
||||||
|
func WithNamingStrategy(strategy schema.NamingStrategy) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.NamingStrategy = strategy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithConnectionPool configures database connection pooling.
|
||||||
|
func WithConnectionPool(maxIdleConns, maxOpenConns int, maxIdleTime, maxLifetime time.Duration) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.MaxIdleConns = maxIdleConns
|
||||||
|
cfg.MaxOpenConns = maxOpenConns
|
||||||
|
cfg.ConnMaxIdleTime = maxIdleTime
|
||||||
|
cfg.ConnMaxLifetime = maxLifetime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDisableForeignKeyConstraintWhenMigrating toggles foreign key constraint creation during migrations.
|
||||||
|
func WithDisableForeignKeyConstraintWhenMigrating(disable bool) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DisableForeignKeyConstraintWhenMigrating = disable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSkipDefaultTransaction toggles default transactions in gorm.
|
||||||
|
func WithSkipDefaultTransaction(skip bool) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.SkipDefaultTransaction = skip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDryRun toggles gorm dry run mode.
|
||||||
|
func WithDryRun(dryRun bool) Option {
|
||||||
|
return func(cfg *config) {
|
||||||
|
cfg.DryRun = dryRun
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user