github.com/erda-project/erda-infra@v1.0.9/providers/mysql/mysql.go (about) 1 // Copyright (c) 2021 Terminus, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package mysql 16 17 import ( 18 "fmt" 19 "reflect" 20 "time" 21 22 _ "github.com/go-sql-driver/mysql" // mysql client driver package 23 "github.com/jinzhu/gorm" 24 25 "github.com/erda-project/erda-infra/base/logs" 26 "github.com/erda-project/erda-infra/base/servicehub" 27 "github.com/erda-project/erda-infra/pkg/mysqldriver" 28 ) 29 30 // Interface . 31 type Interface interface { 32 DB() *gorm.DB 33 } 34 35 var ( 36 interfaceType = reflect.TypeOf((*Interface)(nil)).Elem() 37 gormType = reflect.TypeOf((*gorm.DB)(nil)) 38 ) 39 40 type config struct { 41 MySQLURL string `file:"url" env:"MYSQL_URL"` 42 MySQLHost string `file:"host" env:"MYSQL_HOST" default:"localhost"` 43 MySQLPort string `file:"port" env:"MYSQL_PORT" default:"3306"` 44 MySQLUsername string `file:"username" env:"MYSQL_USERNAME" default:"root"` 45 MySQLPassword string `file:"password" env:"MYSQL_PASSWORD" default:""` 46 MySQLDatabase string `file:"database" env:"MYSQL_DATABASE"` 47 MySQLMaxIdleConns uint64 `file:"max_idle_conns" env:"MYSQL_MAXIDLECONNS" default:"10"` 48 MySQLMaxOpenConns uint64 `file:"max_open_conns" env:"MYSQL_MAXOPENCONNS" default:"20"` 49 MySQLMaxLifeTime time.Duration `file:"max_lifetime" env:"MYSQL_MAXLIFETIME" default:"30m"` 50 MySQLDebug bool `file:"debug" env:"MYSQL_DEBUG" default:"false"` 51 MySQLCharset string `file:"charset" env:"MYSQL_CHARSET" default:"utf8mb4"` 52 MySQLTLS string `file:"tls" env:"MYSQL_TLS"` 53 MySQLCaCertPath string `file:"ca_cert_path" env:"MYSQL_CACERTPATH"` 54 MySQLClientCertPath string `file:"client_cert_path" env:"MYSQL_CLIENTCERTPATH"` 55 MySQLClientKeyPath string `file:"client_key_path" env:"MYSQL_CLIENTKEYPATH"` 56 } 57 58 func (c *config) url() string { 59 if c.MySQLURL != "" { 60 return c.MySQLURL 61 } 62 63 url := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=True&loc=Local", 64 c.MySQLUsername, c.MySQLPassword, c.MySQLHost, c.MySQLPort, c.MySQLDatabase, c.MySQLCharset) 65 if c.MySQLTLS != "" { 66 url = fmt.Sprintf("%v&tls=%s", url, c.MySQLTLS) 67 } 68 return url 69 } 70 71 // provider . 72 type provider struct { 73 Cfg *config 74 Log logs.Logger 75 db *gorm.DB 76 } 77 78 // Init . 79 func (p *provider) Init(ctx servicehub.Context) error { 80 err := mysqldriver.OpenTLS(p.Cfg.MySQLTLS, p.Cfg.MySQLCaCertPath, p.Cfg.MySQLClientCertPath, p.Cfg.MySQLClientKeyPath) 81 if err != nil { 82 return err 83 } 84 85 db, err := gorm.Open("mysql", p.Cfg.url()) 86 if err != nil { 87 return fmt.Errorf("fail to connect mysql: %s", err) 88 } 89 90 // connection pool 91 db.DB().SetMaxIdleConns(int(p.Cfg.MySQLMaxIdleConns)) 92 db.DB().SetMaxOpenConns(int(p.Cfg.MySQLMaxOpenConns)) 93 db.DB().SetConnMaxLifetime(p.Cfg.MySQLMaxLifeTime) 94 p.db = db 95 if p.Cfg.MySQLDebug { 96 p.db = p.db.Debug() 97 } 98 return nil 99 } 100 101 func (p *provider) DB() *gorm.DB { return p.db } 102 103 func (p *provider) Provide(ctx servicehub.DependencyContext, args ...interface{}) interface{} { 104 if ctx.Service() == "mysql-client" || ctx.Type() == gormType { 105 return p.db 106 } 107 return p 108 } 109 110 func init() { 111 servicehub.Register("mysql", &servicehub.Spec{ 112 Services: []string{"mysql", "mysql-client"}, 113 Types: []reflect.Type{ 114 interfaceType, gormType, 115 }, 116 Description: "mysql", 117 ConfigFunc: func() interface{} { return &config{} }, 118 Creator: func() servicehub.Provider { 119 return &provider{} 120 }, 121 }) 122 }