db_mysql.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. package db
  2. import (
  3. "bytes"
  4. MYSQL "database/sql"
  5. "encoding/json"
  6. "fmt"
  7. "io/ioutil"
  8. "os"
  9. "os/exec"
  10. "path"
  11. "path/filepath"
  12. "runtime"
  13. "scd_check_tools/conf"
  14. "scd_check_tools/global"
  15. "scd_check_tools/logger"
  16. "scd_check_tools/tools"
  17. "strings"
  18. "time"
  19. "github.com/astaxie/beego/orm"
  20. _ "github.com/go-sql-driver/mysql"
  21. )
  22. var DbCfg = DbConfig{}
  23. type DbConfig struct {
  24. Host string `json:"host"`
  25. Port string `json:"port"`
  26. User string `json:"user"`
  27. Pwd string `json:"pwd"`
  28. Db string `json:"dbname"`
  29. Charset string `json:"charset"`
  30. }
  31. //返回一个新的orm对象
  32. func CreateOrm() orm.Ormer {
  33. return orm.NewOrm()
  34. }
  35. func ConnDB(cnfpath string) (*MYSQL.DB, error) {
  36. fmt.Println(tools.NowTime()+" 加载数据库配置文件", cnfpath)
  37. fileHanlder, err := os.Open(cnfpath)
  38. if err != nil {
  39. fmt.Printf(tools.NowTime()+" 配置文件%s加载失败:%s\r", cnfpath, err)
  40. os.Exit(1)
  41. }
  42. txt, _ := ioutil.ReadAll(fileHanlder)
  43. fileHanlder.Close()
  44. txtStr := string(txt)
  45. if txtStr == "" {
  46. fmt.Println(tools.NowTime() + " 配置文件格式不正确,请正确配置")
  47. os.Exit(1)
  48. }
  49. cfgdata := DbConfig{}
  50. err = json.Unmarshal(txt, &cfgdata)
  51. if err != nil {
  52. fmt.Println(tools.NowTime()+" 配置文件解析失败:", err)
  53. os.Exit(1)
  54. }
  55. DbCfg = cfgdata
  56. if cfgdata.Port == "" {
  57. cfgdata.Port = "3306"
  58. }
  59. if cfgdata.Charset == "" {
  60. cfgdata.Charset = "utf8"
  61. }
  62. //urll:=root:11111111@tcp(127.0.0.1:3306)/mytest?charset=utf8
  63. url := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", cfgdata.User, cfgdata.Pwd, cfgdata.Host, cfgdata.Port, cfgdata.Db, cfgdata.Charset)
  64. conn, err := MYSQL.Open("mysql", url)
  65. if err != nil {
  66. return conn, err
  67. }
  68. fmt.Println(tools.NowTime() + " Mysql数据库连接成功")
  69. global.MysqlConn = conn
  70. err = orm.RegisterDataBase("default", "mysql", url, 1, 100)
  71. if err != nil {
  72. logger.Logger.Debug("连接本地数据库" + cfgdata.Db + "失败:" + err.Error())
  73. if strings.Index(err.Error(), "Unknown database") > -1 {
  74. //数据库未创建,连接到mysql数据再创建业务数据库
  75. crdbSql := "CREATE DATABASE " + cfgdata.Db + " DEFAULT CHARSET utf8 COLLATE utf8_general_ci"
  76. adminConn, cerr := MYSQL.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", cfgdata.User, cfgdata.Pwd, cfgdata.Host, cfgdata.Port, "mysql", cfgdata.Charset))
  77. if cerr != nil {
  78. tools.Error("连接本地数据库mysql失败," + err.Error())
  79. os.Exit(1)
  80. }
  81. _, cerr = adminConn.Exec(crdbSql)
  82. if cerr != nil {
  83. logger.Logger.Error(cerr, fmt.Sprintf("判断并创建数据库"+cfgdata.Db+"时失败:"+cerr.Error()))
  84. os.Exit(1)
  85. }
  86. err = orm.RegisterDataBase("default", "mysql", url, 30)
  87. if err != nil {
  88. logger.Logger.Error(err.Error())
  89. os.Exit(1)
  90. }
  91. }
  92. }
  93. if conf.GlobalConfig["loglevel"] == "5" {
  94. orm.Debug = true
  95. }
  96. orm.SetMaxIdleConns("default", 5)
  97. orm.SetMaxOpenConns("default", 200)
  98. db, _ := orm.GetDB("default")
  99. db.SetConnMaxLifetime(60 * time.Minute)
  100. sql := "select param_value from global_sys_param where param_name=? "
  101. o := orm.NewOrm()
  102. datas := []orm.Params{}
  103. _, dberr := o.Raw(sql, "db_script_version").Values(&datas)
  104. //CacheMonitorPoint()
  105. f, _ := exec.LookPath(os.Args[0])
  106. fp, _ := filepath.Abs(f)
  107. i := strings.LastIndex(fp, string(os.PathSeparator))
  108. prjDir := string(fp[0:i])
  109. prjDir = prjDir + string(os.PathSeparator) + "db" + string(os.PathSeparator)
  110. if dberr != nil {
  111. logger.Logger.Println("检测到系统数据库还未进行初始化创建,开始进行...")
  112. fileHanlder, err = os.Open("db/db_init.sql")
  113. if err != nil {
  114. logger.Logger.Println(" 数据库初始化脚本文件db/db_init.sql加载失败:" + err.Error())
  115. return nil, err
  116. }
  117. //txt, _ = ioutil.ReadAll(fileHanlder)
  118. fileHanlder.Close()
  119. var commandName = "mysql"
  120. logger.Logger.Println("正在执行数据库初始化脚本文件db/db_init.sql")
  121. logger.Logger.Println(commandName + " -h" + cfgdata.Host + " -P" + cfgdata.Port + " -u" + cfgdata.User + " -p" + cfgdata.Pwd + " -D" + cfgdata.Db + " <" + prjDir + "db_init.sql")
  122. var cmdErr bytes.Buffer
  123. if runtime.GOOS == "windows" {
  124. cmd := exec.Command(commandName, "-h"+cfgdata.Host, "-P"+cfgdata.Port, "-u"+cfgdata.User, "-p"+cfgdata.Pwd, "-D"+cfgdata.Db, "-e", "source "+prjDir+"db_init.sql")
  125. cmd.Stderr = &cmdErr
  126. err = cmd.Run()
  127. } else {
  128. cmd := exec.Command("sh", "-c", "mysql -h"+cfgdata.Host+" -P"+cfgdata.Port+" -u"+cfgdata.User+" -p"+cfgdata.Pwd+" -D"+cfgdata.Db+" <"+prjDir+"db_init.sql")
  129. cmd.Stderr = &cmdErr
  130. err = cmd.Run()
  131. }
  132. if err != nil {
  133. logger.Logger.Println("数据库更新脚本文件db/db_init.sql执行失败:" + cmdErr.String())
  134. logger.Logger.Error(err)
  135. logger.Logger.Println(cmdErr.String())
  136. return nil, err
  137. }
  138. }
  139. db_script_version := ""
  140. if len(datas) > 0 {
  141. db_script_version = tools.IsEmpty(datas[0]["param_value"])
  142. } else {
  143. o.Raw("insert into global_sys_param (param_name,param_value,param_memo)values(?,?,?)", "db_script_version", "0", "数据库脚本版本").Exec()
  144. }
  145. //检查是否有数据库更新脚本
  146. //数据库更新脚本名称规则:db_update_v{NO}.sql,其中{NO}为版本号。版本号为脚本编写者指定,但必须为比上一版本号大的整数
  147. //数据库更新为单次迭代执行,所以可以同时放置多次更新脚本文件
  148. //如需要从初始化脚本开始进行数据库还原,可以手动清除global_sys_param表中db_script_version项值为0或指定版本号
  149. dbUpdatefile, err2 := ioutil.ReadDir("./db")
  150. if err2 == nil {
  151. var commandName = "mysql"
  152. for _, fsitem := range dbUpdatefile {
  153. fs_n := fsitem.Name()
  154. filepath.Walk(fs_n, func(fpath string, fi os.FileInfo, err error) error {
  155. if path.Ext(fpath) == ".sql" && strings.HasPrefix(fpath, "db_update_v") {
  156. script_v := strings.Replace(fs_n, "db_update_v", "", 1)
  157. script_v = strings.Trim(strings.Replace(script_v, ".sql", "", 1), " ")
  158. if db_script_version == "" || script_v > db_script_version {
  159. fileHanlder, err = os.Open("db/" + fs_n)
  160. if err != nil {
  161. logger.Logger.Println(" 数据库更新脚本文件db/" + fs_n + "加载失败:" + err.Error())
  162. return nil
  163. }
  164. fileHanlder.Close()
  165. logger.Logger.Println(tools.NowTime() + " 正在执行数据库更新脚本文件" + prjDir + fs_n)
  166. var cmdErr bytes.Buffer
  167. if runtime.GOOS == "windows" {
  168. cmd := exec.Command(commandName, "-h"+cfgdata.Host, "-P"+cfgdata.Port, "-u"+cfgdata.User, "-p"+cfgdata.Pwd, "-D"+cfgdata.Db, "-e", "source "+prjDir+fs_n)
  169. cmd.Stderr = &cmdErr
  170. err = cmd.Run()
  171. } else {
  172. cmd := exec.Command("sh", "-c", "mysql -h"+cfgdata.Host+" -P"+cfgdata.Port+" -u"+cfgdata.User+" -p"+cfgdata.Pwd+" -D"+cfgdata.Db+" <"+prjDir+fs_n)
  173. cmd.Stderr = &cmdErr
  174. err = cmd.Run()
  175. }
  176. if err != nil {
  177. logger.Logger.Println(fmt.Sprintf("%v", cfgdata))
  178. logger.Logger.Println(err)
  179. logger.Logger.Println(cmdErr.String())
  180. logger.Logger.Println("数据库更新脚本文件db/" + fs_n + "执行失败:" + cmdErr.String())
  181. return err
  182. }
  183. o.Raw("update global_sys_param set param_value=? where param_name=?", script_v, "db_script_version").Exec()
  184. }
  185. }
  186. return nil
  187. })
  188. }
  189. } else {
  190. logger.Logger.Error(err2)
  191. }
  192. for i := 0; i < 5; i++ {
  193. global.DbConnOK <- true
  194. time.Sleep(20 * time.Millisecond)
  195. }
  196. return conn, nil
  197. }
  198. func CloseDB() {
  199. if global.MysqlConn != nil {
  200. global.MysqlConn.Close()
  201. }
  202. }
  203. func CheckErr(err error) {
  204. if err != nil {
  205. fmt.Println(tools.NowTime() + ":" + err.Error())
  206. panic(err)
  207. }
  208. }
  209. //获取Mysql安装目录
  210. func getMysqlInsall() (string, error) {
  211. mysqlInstall := ""
  212. o := orm.NewOrm()
  213. var sqlCommandText = "select @@basedir as base_path from dual"
  214. var tableData []orm.Params
  215. _, err := o.Raw(sqlCommandText).Values(&tableData)
  216. if err == nil {
  217. mysqlInstall = tableData[0]["base_path"].(string)
  218. }
  219. return mysqlInstall, err
  220. }