github.com/artisanhe/tools@v1.0.1-0.20210607022958-19a8fef2eb04/sqlx/mysql/db.go (about)

     1  package mysql
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"time"
     7  
     8  	"github.com/artisanhe/tools/conf"
     9  	"github.com/artisanhe/tools/conf/presets"
    10  	"github.com/artisanhe/tools/sqlx"
    11  )
    12  
    13  type MySQL struct {
    14  	Name            string
    15  	Host            string `conf:"upstream" validate:"@hostname"`
    16  	Port            int
    17  	User            string           `conf:"env" validate:"@string[1,)"`
    18  	Password        presets.Password `conf:"env" validate:"@string[1,)"`
    19  	Extra           string
    20  	PoolSize        int
    21  	ConnMaxLifetime time.Duration
    22  	presets.Retry
    23  	db *sqlx.DB
    24  }
    25  
    26  func (m MySQL) DockerDefaults() conf.DockerDefaults {
    27  	return conf.DockerDefaults{
    28  		"Host": conf.RancherInternal("tool-dbs", m.Name),
    29  		"Port": 3306,
    30  	}
    31  }
    32  
    33  func (m MySQL) MarshalDefaults(v interface{}) {
    34  	if mysql, ok := v.(*MySQL); ok {
    35  		mysql.Retry.MarshalDefaults(&mysql.Retry)
    36  
    37  		if mysql.Port == 0 {
    38  			mysql.Port = 3306
    39  		}
    40  
    41  		if mysql.PoolSize == 0 {
    42  			mysql.PoolSize = 10
    43  		}
    44  
    45  		if mysql.ConnMaxLifetime == 0 {
    46  			mysql.ConnMaxLifetime = 4 * time.Hour
    47  		}
    48  
    49  		if mysql.Extra == "" {
    50  			values := url.Values{}
    51  			values.Set("charset", "utf8")
    52  			values.Set("parseTime", "true")
    53  			values.Set("interpolateParams", "true")
    54  			values.Set("autocommit", "true")
    55  			values.Set("loc", "Local")
    56  			mysql.Extra = values.Encode()
    57  		}
    58  	}
    59  }
    60  
    61  func (m MySQL) GetConnect() string {
    62  	return fmt.Sprintf("%s:%s@tcp(%s:%d)/?%s", m.User, m.Password, m.Host, m.Port, m.Extra)
    63  }
    64  
    65  func (m *MySQL) Connect() error {
    66  	m.MarshalDefaults(m)
    67  	db, err := sqlx.Open("logger:mysql", m.GetConnect())
    68  	if err != nil {
    69  		return err
    70  	}
    71  	db.SetMaxOpenConns(m.PoolSize)
    72  	db.SetMaxIdleConns(m.PoolSize / 2)
    73  	db.SetConnMaxLifetime(m.ConnMaxLifetime)
    74  	m.db = db
    75  	return nil
    76  }
    77  
    78  func (m *MySQL) Init() {
    79  	if m.db == nil {
    80  		m.Do(m.Connect)
    81  	}
    82  }
    83  
    84  func (m *MySQL) Get() *sqlx.DB {
    85  	if m.db == nil {
    86  		panic(fmt.Errorf("get db before init"))
    87  	}
    88  	return m.db
    89  }
    90  
    91  type DBGetter interface {
    92  	Get() *sqlx.DB
    93  }