mysql_dialect.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package migrator
  2. import (
  3. "fmt"
  4. "strconv"
  5. "strings"
  6. "github.com/VividCortex/mysqlerr"
  7. "github.com/go-sql-driver/mysql"
  8. "github.com/go-xorm/xorm"
  9. )
  10. type Mysql struct {
  11. BaseDialect
  12. }
  13. func NewMysqlDialect(engine *xorm.Engine) *Mysql {
  14. d := Mysql{}
  15. d.BaseDialect.dialect = &d
  16. d.BaseDialect.engine = engine
  17. d.BaseDialect.driverName = MYSQL
  18. return &d
  19. }
  20. func (db *Mysql) SupportEngine() bool {
  21. return true
  22. }
  23. func (db *Mysql) Quote(name string) string {
  24. return "`" + name + "`"
  25. }
  26. func (db *Mysql) AutoIncrStr() string {
  27. return "AUTO_INCREMENT"
  28. }
  29. func (db *Mysql) BooleanStr(value bool) string {
  30. if value {
  31. return "1"
  32. }
  33. return "0"
  34. }
  35. func (db *Mysql) SqlType(c *Column) string {
  36. var res string
  37. switch c.Type {
  38. case DB_Bool:
  39. res = DB_TinyInt
  40. c.Length = 1
  41. case DB_Serial:
  42. c.IsAutoIncrement = true
  43. c.IsPrimaryKey = true
  44. c.Nullable = false
  45. res = DB_Int
  46. case DB_BigSerial:
  47. c.IsAutoIncrement = true
  48. c.IsPrimaryKey = true
  49. c.Nullable = false
  50. res = DB_BigInt
  51. case DB_Bytea:
  52. res = DB_Blob
  53. case DB_TimeStampz:
  54. res = DB_Char
  55. c.Length = 64
  56. case DB_NVarchar:
  57. res = DB_Varchar
  58. default:
  59. res = c.Type
  60. }
  61. var hasLen1 = (c.Length > 0)
  62. var hasLen2 = (c.Length2 > 0)
  63. if res == DB_BigInt && !hasLen1 && !hasLen2 {
  64. c.Length = 20
  65. hasLen1 = true
  66. }
  67. if hasLen2 {
  68. res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")"
  69. } else if hasLen1 {
  70. res += "(" + strconv.Itoa(c.Length) + ")"
  71. }
  72. switch c.Type {
  73. case DB_Char, DB_Varchar, DB_NVarchar, DB_TinyText, DB_Text, DB_MediumText, DB_LongText:
  74. res += " CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
  75. }
  76. return res
  77. }
  78. func (db *Mysql) TableCheckSql(tableName string) (string, []interface{}) {
  79. args := []interface{}{"grafana", tableName}
  80. sql := "SELECT `TABLE_NAME` from `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_SCHEMA`=? and `TABLE_NAME`=?"
  81. return sql, args
  82. }
  83. func (db *Mysql) UpdateTableSql(tableName string, columns []*Column) string {
  84. var statements = []string{}
  85. statements = append(statements, "DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci")
  86. for _, col := range columns {
  87. statements = append(statements, "MODIFY "+col.StringNoPk(db))
  88. }
  89. return "ALTER TABLE " + db.Quote(tableName) + " " + strings.Join(statements, ", ") + ";"
  90. }
  91. func (db *Mysql) CleanDB() error {
  92. tables, _ := db.engine.DBMetas()
  93. sess := db.engine.NewSession()
  94. defer sess.Close()
  95. for _, table := range tables {
  96. if _, err := sess.Exec("set foreign_key_checks = 0"); err != nil {
  97. return fmt.Errorf("failed to disable foreign key checks")
  98. }
  99. if _, err := sess.Exec("drop table " + table.Name + " ;"); err != nil {
  100. return fmt.Errorf("failed to delete table: %v, err: %v", table.Name, err)
  101. }
  102. if _, err := sess.Exec("set foreign_key_checks = 1"); err != nil {
  103. return fmt.Errorf("failed to disable foreign key checks")
  104. }
  105. }
  106. return nil
  107. }
  108. func (db *Mysql) IsUniqueConstraintViolation(err error) bool {
  109. if driverErr, ok := err.(*mysql.MySQLError); ok {
  110. if driverErr.Number == mysqlerr.ER_DUP_ENTRY {
  111. return true
  112. }
  113. }
  114. return false
  115. }