package dbquery import ( "database/sql" "fmt" "log" "net/url" "errors" "strings" "time" _ "dm" "git.tetele.net/tgo/helper" _ "gitee.com/opengauss/openGauss-connector-go-pq" // 高斯驱动(推荐)或 "github.com/lib/pq" _ "github.com/go-sql-driver/mysql" //_ "github.com/lib/pq" // 关键驱动导入 ) var DB *sql.DB var SLAVER_DB *sql.DB // db类型,默认空,如TencentDB(腾讯), var DB_PROVIDER string func Connect(DBHOST, DBUSER, DBPWD, DBNAME, DBPORT string, conns ...int) error { log.Println("mysql database connectting...") var dbConnErr error const maxRetries = 10 if DBHOST == "" || DBUSER == "" || DBPWD == "" || DBPORT == "" { return errors.New("mysql DBconnection params errors") } dsn := DBUSER + ":" + DBPWD + "@tcp(" + DBHOST + ":" + DBPORT + ")/" + DBNAME + "?charset=utf8mb4" for i := 0; i < maxRetries; i++ { //Open并不真正建立连接,它只是创建一个连接对象,实际的连接是延迟建立的。通过ping来检测(账号密码和网络问题) // 每次尝试创建新连接对象 DB, dbConnErr = sql.Open("mysql", dsn) if dbConnErr != nil { log.Println("sql open failed:", i+1, dbConnErr) time.Sleep(time.Second * 5) continue } // 验证连接有效性 if pingErr := DB.Ping(); pingErr != nil { DB.Close() // 记录真实错误信息 dbConnErr = pingErr log.Println("ping failed:", i+1, pingErr) time.Sleep(time.Second * 5) continue } if len(conns) > 0 { DB.SetMaxOpenConns(conns[0]) //用于设置最大打开的连接数,默认值为0表示不限制 } else { DB.SetMaxOpenConns(200) //默认值为0表示不限制 } if len(conns) > 1 { DB.SetMaxIdleConns(conns[1]) //用于设置闲置的连接数 } else { DB.SetMaxIdleConns(50) } log.Println("mysql database connected") DB.SetConnMaxLifetime(time.Minute * 2) return nil } return fmt.Errorf("after %d attempts: %w", maxRetries, dbConnErr) } func CloseConn() error { return DB.Close() } func ConnectSlaver(DBHOST, DBUSER_SLAVER, DBPWD_SLAVER, DBNAME, DBPORT string, conns ...int) error { log.Println("database connectting with slaver...") var dbConnErr error if DBHOST != "" && DBUSER_SLAVER != "" && DBPWD_SLAVER != "" && DBPORT != "" { //&& DBNAME != "" for i := 0; i < 10; i++ { SLAVER_DB, dbConnErr = sql.Open("mysql", DBUSER_SLAVER+":"+DBPWD_SLAVER+"@tcp("+DBHOST+":"+DBPORT+")/"+DBNAME+"?charset=utf8mb4") if dbConnErr != nil { log.Println("ERROR", "can not connect to Database, ", dbConnErr) time.Sleep(time.Second * 5) } else { if len(conns) > 0 { SLAVER_DB.SetMaxOpenConns(conns[0]) //用于设置最大打开的连接数,默认值为0表示不限制 } else { SLAVER_DB.SetMaxOpenConns(200) //默认值为0表示不限制 } if len(conns) > 1 { SLAVER_DB.SetMaxIdleConns(conns[1]) //用于设置闲置的连接数 } else { SLAVER_DB.SetMaxIdleConns(50) } SLAVER_DB.Ping() log.Println("database connected") SLAVER_DB.SetConnMaxLifetime(time.Minute * 2) break } } } else { return errors.New("db connection params errors") } return dbConnErr } func CloseSlaverConn() error { return SLAVER_DB.Close() } /** * 检测表名 */ func getTableName(dbName, table string, dbtype ...string) string { var db_type string = "mysql" if DB_PROVIDER == "PgsqlDb" { dbName = "" } else if DB_PROVIDER == "DmSql" { dbName = "" } if len(dbtype) > 0 { if dbtype[0] != "" { db_type = dbtype[0] } } var ret string switch db_type { case "mysql": if strings.Contains(table, ".") { ret = table } if dbName != "" { if strings.Contains(table, ",") { arr := strings.Split(table, ",") arrStrs := make([]string, 0, len(arr)) for _, v := range arr { arrStrs = append(arrStrs, helper.StringJoin(dbName, ".", v)) } ret = strings.Join(arrStrs, ",") } else { ret = helper.StringJoin(dbName, ".", table) } } else { ret = table } case "mssql": ret = helper.StringJoin(dbName, ".", table) } return ret } func GetDbTableName(dbName, table string) string { return getTableName(dbName, table) } func judg() []string { return []string{"=", ">", "<", "!=", "<=", ">="} } // pgsql连接 func PgConnect(DBHOST, DBUSER, DBPWD, DBNAME, DBPORT string, conns ...int) error { log.Println("pg database connectting...") var dbConnErr error const maxRetries = 10 DB_PROVIDER = "PgsqlDb" if DBHOST == "" || DBUSER == "" || DBPWD == "" || DBPORT == "" { return errors.New("pgsql DBconnection params errors") } dsn := "host=" + DBHOST + " port=" + DBPORT + " user=" + DBUSER + " password=" + DBPWD + " dbname=" + DBNAME + " sslmode=disable search_path=public" log.Println("database dsn", dsn) for i := 0; i < maxRetries; i++ { //Open并不真正建立连接,它只是创建一个连接对象,实际的连接是延迟建立的。通过ping来检测(账号密码和网络问题) // 每次尝试创建新连接对象 DB, dbConnErr = sql.Open("opengauss", dsn) if dbConnErr != nil { log.Println("sql open failed:", i+1, dbConnErr) time.Sleep(time.Second * 5) continue } // 验证连接有效性 if pingErr := DB.Ping(); pingErr != nil { DB.Close() // 记录真实错误信息 dbConnErr = pingErr log.Println("ping failed:", i+1, pingErr) time.Sleep(time.Second * 5) continue } if len(conns) > 0 { DB.SetMaxOpenConns(conns[0]) //用于设置最大打开的连接数,默认值为0表示不限制 } else { DB.SetMaxOpenConns(200) //默认值为0表示不限制 } if len(conns) > 1 { DB.SetMaxIdleConns(conns[1]) //用于设置闲置的连接数 } else { DB.SetMaxIdleConns(50) } log.Println("pgsql database connected") DB.SetConnMaxLifetime(time.Minute * 2) return nil } return fmt.Errorf("after %d attempts: %w", maxRetries, dbConnErr) } // 达梦8连接 func DmConnect(DBHOST, DBUSER, DBPWD, DBNAME, DBPORT string, conns ...int) error { log.Println("DM database connectting...") var dbConnErr error const maxRetries = 10 DB_PROVIDER = "DmSql" if DBHOST == "" || DBUSER == "" || DBPWD == "" || DBPORT == "" { return errors.New("dm DBconnection params errors") } //达梦8如果密码存在特殊字符,需使用 url.PathEscape 进行转义后再放入连接串 DBPWD = url.PathEscape(DBPWD) dsn := "dm://" + DBUSER + ":" + DBPWD + "@" + DBHOST + ":" + DBPORT + "?charSet=utf8&compatibleMode=mysql" log.Println("database dsn", dsn) for i := 0; i < maxRetries; i++ { //Open并不真正建立连接,它只是创建一个连接对象,实际的连接是延迟建立的。通过ping来检测(账号密码和网络问题) // 每次尝试创建新连接对象 DB, dbConnErr = sql.Open("dm", dsn) if dbConnErr != nil { log.Println("sql open failed:", i+1, dbConnErr) time.Sleep(time.Second * 5) continue } // 验证连接有效性 if pingErr := DB.Ping(); pingErr != nil { DB.Close() // 记录真实错误信息 dbConnErr = pingErr log.Println("ping failed:", i+1, pingErr) time.Sleep(time.Second * 5) continue } if len(conns) > 0 { DB.SetMaxOpenConns(conns[0]) //用于设置最大打开的连接数,默认值为0表示不限制 } else { DB.SetMaxOpenConns(200) //默认值为0表示不限制 } if len(conns) > 1 { DB.SetMaxIdleConns(conns[1]) //用于设置闲置的连接数 } else { DB.SetMaxIdleConns(50) } log.Println("dm database connected") DB.SetConnMaxLifetime(time.Minute * 2) return nil } return fmt.Errorf("after %d attempts: %w", maxRetries, dbConnErr) }