github.com/team-ide/go-dialect@v1.9.20/dialect/back/dialect_mysql.go (about) 1 package back 2 3 import ( 4 "errors" 5 "strings" 6 ) 7 8 func NewMysqlDialect() *MysqlDialect { 9 10 res := &MysqlDialect{ 11 DefaultDialect: NewDefaultDialect(MysqlType), 12 } 13 res.init() 14 return res 15 } 16 17 type MysqlDialect struct { 18 *DefaultDialect 19 } 20 21 func (this_ *MysqlDialect) init() { 22 /** 数值类型 **/ 23 /** 24 MySQL 支持所有标准 SQL 数值数据类型。 25 这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL 和 NUMERIC),以及近似数值数据类型(FLOAT、REAL 和 DOUBLE PRECISION)。 26 关键字INT是INTEGER的同义词,关键字DEC是DECIMAL的同义词。 27 BIT数据类型保存位字段值,并且支持 MyISAM、MEMORY、InnoDB 和 BDB表。 28 作为 SQL 标准的扩展,MySQL 也支持整数类型 TINYINT、MEDIUMINT 和 BIGINT。下面的表显示了需要的每个整数类型的存储和范围。 29 30 如果不设置长度,会有默认的长度 31 长度代表了显示的最大宽度,如果不够会用0在左边填充,但必须搭配zerofill 使用! 32 例如: 33 INT(7) 括号中7不是指范围,范围是由数据类型决定的,只是代表显示结果的宽度 34 */ 35 36 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "BIT", TypeFormat: "BIT($l)", HasLength: false, IsNumber: true}) 37 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "TINYINT", TypeFormat: "TINYINT($l)", HasLength: true, IsNumber: true}) 38 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "SMALLINT", TypeFormat: "SMALLINT($l)", HasLength: true, IsNumber: true}) 39 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "MEDIUMINT", TypeFormat: "MEDIUMINT($l)", HasLength: true, IsNumber: true}) 40 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "INT", TypeFormat: "INT($l)", HasLength: true, IsNumber: true}) 41 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "INTEGER", TypeFormat: "INTEGER($l)", HasLength: true, IsNumber: true}) 42 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "BIGINT", TypeFormat: "BIGINT($l)", HasLength: true, IsNumber: true}) 43 44 /** 小数 **/ 45 46 /** 47 M:整数部位+小数部位 48 D:小数部位 49 如果超过范围,则插入临界值 50 M和D都可以省略 51 如果是DECIMAL,则M默认为10,D默认为0 52 如果是FLOAT和DOUBLE,则会根据插入的数值的精度来决定精度 53 定点型的精确度较高,如果要求插入数值的精度较高如货币运算等则考虑使用 54 原则:所选择的类型越简单越好,能保存数值的类型越小越好 55 */ 56 57 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "FLOAT", TypeFormat: "FLOAT($l, $d)", HasLength: true, HasDecimal: true, IsNumber: true}) 58 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "DOUBLE", TypeFormat: "DOUBLE($l, $d)", HasLength: true, HasDecimal: true, IsNumber: true}) 59 60 /** 61 DECIMAL。浮点数类型和定点数类型都可以用(M,N)来表示。其中,M称为精度,表示总共的位数;N称为标度,表示小数的位数.DECIMAL若不指定精度则默认为(10,0) 62 不论是定点数还是浮点数类型,如果用户指定的精度超出精度范围,则会四舍五入 63 */ 64 65 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "DEC", TypeFormat: "DEC($l, $d)", HasLength: true, IsNumber: true}) 66 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "DECIMAL", TypeFormat: "DOUBLE($l, $d)", HasLength: true, IsNumber: true}) 67 68 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "NUMBER", TypeFormat: "NUMBER($l, $d)", HasLength: true, IsNumber: true}) 69 70 /** 日期/时间类型 **/ 71 /** 72 表示时间值的日期和时间类型为DATETIME、DATE、TIMESTAMP、TIME和YEAR。 73 每个时间类型有一个有效值范围和一个"零"值,当指定不合法的MySQL不能表示的值时使用"零"值。 74 TIMESTAMP类型有专有的自动更新特性,将在后面描述。 75 DATE: 76 (1)以‘YYYY-MM-DD’或者‘YYYYMMDD’字符串格式表示的日期,取值范围为‘1000-01-01’~‘9999-12-3’。例如,输入‘2012-12-31’或者‘20121231’,插入数据库的日期都为2012-12-31。 77 (2)以‘YY-MM-DD’或者‘YYMMDD’字符串格式表示的日期,在这里YY表示两位的年值。包含两位年值的日期会令人模糊,因为不知道世纪。MySQL使用以下规则解释两位年值:‘00~69’范围的年值转换为‘2000~2069’;‘70~99’范围的年值转换为‘1970~1999’。例如,输入‘12-12-31’,插入数据库的日期为2012-12-31;输入‘981231’,插入数据的日期为1998-12-31。 78 (3)以YY-MM-DD或者YYMMDD数字格式表示的日期,与前面相似,00~69范围的年值转换为2000~2069,70~99范围的年值转换为1970~1999。例如,输入12-12-31插入数据库的日期为2012-12-31;输入981231,插入数据的日期为1998-12-31 79 */ 80 81 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "YEAR", TypeFormat: "YEAR", IsDateTime: true}) 82 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "TIME", TypeFormat: "TIME", IsDateTime: true}) 83 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "DATE", TypeFormat: "DATE", IsDateTime: true}) 84 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "DATETIME", TypeFormat: "DATETIME", IsDateTime: true}) 85 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "TIMESTAMP", TypeFormat: "TIMESTAMP", IsDateTime: true}) 86 87 /** 字符串类型 **/ 88 /** 89 字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。该节描述了这些类型如何工作以及如何在查询中使用这些类型 90 91 注意:char(n) 和 varchar(n) 中括号中 n 代表字符的个数,并不代表字节个数,比如 CHAR(30) 就可以存储 30 个字符。 92 CHAR 和 VARCHAR 类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。 93 BINARY 和 VARBINARY 类似于 CHAR 和 VARCHAR,不同的是它们包含二进制字符串而不要非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。这说明它们没有字符集,并且排序和比较基于列值字节的数值值。 94 BLOB 是一个二进制大对象,可以容纳可变数量的数据。有 4 种 BLOB 类型:TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。它们区别在于可容纳存储范围不同。 95 有 4 种 TEXT 类型:TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。对应的这 4 种 BLOB 类型,可存储的最大长度不同,可根据实际情况选择。 96 */ 97 98 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "CHAR", TypeFormat: "CHAR($l)", HasLength: true, IsString: true}) 99 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "VARCHAR", TypeFormat: "VARCHAR($l)", HasLength: true, IsString: true}) 100 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "TINYTEXT", TypeFormat: "TINYTEXT($l)", HasLength: true, IsString: true}) 101 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "TEXT", TypeFormat: "TEXT($l)", HasLength: true, IsString: true}) 102 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "MEDIUMTEXT", TypeFormat: "MEDIUMTEXT($l)", HasLength: true, IsString: true}) 103 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "LONGTEXT", TypeFormat: "LONGTEXT", HasLength: false, IsString: true}) 104 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "ENUM", TypeFormat: "ENUM($l)", HasLength: true, IsString: true}) 105 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "TINYBLOB", TypeFormat: "TINYBLOB($l)", HasLength: true, IsString: true}) 106 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "BLOB", TypeFormat: "BLOB($l)", HasLength: true, IsString: true}) 107 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "MEDIUMBLOB", TypeFormat: "MEDIUMBLOB($l)", HasLength: true, IsString: true}) 108 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "LONGBLOB", TypeFormat: "LONGBLOB", HasLength: false, IsString: true}) 109 110 this_.AddColumnTypeInfo(&ColumnTypeInfo{Name: "SET", TypeFormat: "SET($l)", HasLength: true, IsString: true}) 111 112 this_.AddFuncTypeInfo(&FuncTypeInfo{Name: "md5", Format: "md5"}) 113 } 114 115 func (this_ *MysqlDialect) PackOwner(ownerName string) string { 116 return packingName("`", ownerName) 117 } 118 119 func (this_ *MysqlDialect) PackTable(tableName string) string { 120 return packingName("`", tableName) 121 } 122 123 func (this_ *MysqlDialect) PackColumn(columnName string) string { 124 return packingName("`", columnName) 125 } 126 127 func (this_ *MysqlDialect) PackColumns(columnNames []string) string { 128 return packingNames("`", columnNames) 129 } 130 131 func (this_ *MysqlDialect) PackValueForSql(column *ColumnModel, value interface{}) string { 132 var columnTypeInfo *ColumnTypeInfo 133 if column != nil { 134 if strings.EqualFold(column.Type, "ENUM") { 135 if value == nil || value == "" { 136 if !column.NotNull { 137 return "NULL" 138 } 139 } 140 } 141 columnTypeInfo, _ = this_.GetColumnTypeInfo(column.Type) 142 } 143 return packingValue(columnTypeInfo, `'`, `\`, value) 144 } 145 146 func (this_ *MysqlDialect) FormatColumnType(column *ColumnModel) (columnType string, err error) { 147 if strings.EqualFold(column.Type, "SET") || strings.EqualFold(column.Type, "ENUM") { 148 columnType = column.Type + "(" + packingValues("'", column.Defaults) + ")" 149 return 150 } 151 columnTypeInfo, err := this_.GetColumnTypeInfo(column.Type) 152 if err != nil { 153 return 154 } 155 columnType = columnTypeInfo.FormatColumnType(column.Length, column.Decimal) 156 return 157 } 158 func (this_ *MysqlDialect) FormatDefaultValue(column *ColumnModel) (defaultValue string) { 159 defaultValue = "DEFAULT " 160 if column.DefaultCurrentTimestamp || column.OnUpdateCurrentTimestamp { 161 if column.DefaultCurrentTimestamp { 162 defaultValue += " CURRENT_TIMESTAMP " 163 } 164 if column.OnUpdateCurrentTimestamp { 165 defaultValue += " ON UPDATE CURRENT_TIMESTAMP " 166 } 167 return 168 } 169 defaultValue += this_.PackValueForSql(nil, column.Default) 170 return 171 } 172 func (this_ *MysqlDialect) OwnerModel(data map[string]interface{}) (owner *OwnerModel, err error) { 173 if data == nil { 174 return 175 } 176 owner = &OwnerModel{} 177 if data["SCHEMA_NAME"] != nil { 178 owner.Name = data["SCHEMA_NAME"].(string) 179 } 180 if data["DEFAULT_CHARACTER_SET_NAME"] != nil { 181 owner.CharacterSetName = data["DEFAULT_CHARACTER_SET_NAME"].(string) 182 } 183 if data["DEFAULT_COLLATION_NAME"] != nil { 184 owner.CollationName = data["DEFAULT_COLLATION_NAME"].(string) 185 } 186 return 187 } 188 func (this_ *MysqlDialect) OwnersSelectSql() (sql string, err error) { 189 sql = `SELECT SCHEMA_NAME,DEFAULT_CHARACTER_SET_NAME,DEFAULT_COLLATION_NAME from information_schema.schemata ORDER BY SCHEMA_NAME` 190 return 191 } 192 func (this_ *MysqlDialect) OwnerSelectSql(ownerName string) (sql string, err error) { 193 sql = `SELECT SCHEMA_NAME,DEFAULT_CHARACTER_SET_NAME,DEFAULT_COLLATION_NAME from information_schema.schemata ` 194 sql += ` WHERE SCHEMA_NAME='` + ownerName + `'` 195 return 196 } 197 func (this_ *MysqlDialect) OwnerChangeSql(ownerName string) (sql string, err error) { 198 sql += `USE ` + this_.PackOwner(ownerName) 199 return 200 } 201 func (this_ *MysqlDialect) OwnerCreateSql(owner *OwnerModel) (sqlList []string, err error) { 202 var sql string 203 sql = `CREATE DATABASE ` + this_.PackOwner(owner.Name) 204 if owner.CharacterSetName != "" { 205 sql += ` CHARACTER SET ` + owner.CharacterSetName 206 } 207 if owner.CollationName != "" { 208 sql += ` COLLATE '` + owner.CollationName + "'" 209 } 210 211 sqlList = append(sqlList, sql) 212 return 213 } 214 func (this_ *MysqlDialect) OwnerDeleteSql(ownerName string) (sqlList []string, err error) { 215 var sql string 216 sql = `DROP DATABASE IF EXISTS ` + this_.PackOwner(ownerName) 217 218 sqlList = append(sqlList, sql) 219 return 220 } 221 222 func (this_ *MysqlDialect) TableModel(data map[string]interface{}) (table *TableModel, err error) { 223 if data == nil { 224 return 225 } 226 table = &TableModel{} 227 if data["TABLE_NAME"] != nil { 228 table.Name = data["TABLE_NAME"].(string) 229 } 230 if data["TABLE_COMMENT"] != nil { 231 table.Comment = data["TABLE_COMMENT"].(string) 232 } 233 if data["TABLE_SCHEMA"] != nil { 234 table.OwnerName = data["TABLE_SCHEMA"].(string) 235 } 236 return 237 } 238 func (this_ *MysqlDialect) TablesSelectSql(ownerName string) (sql string, err error) { 239 sql = `SELECT TABLE_NAME,TABLE_COMMENT,TABLE_SCHEMA from information_schema.tables ` 240 if ownerName != "" { 241 sql += `WHERE TABLE_SCHEMA='` + ownerName + `' ` 242 } 243 sql += `ORDER BY TABLE_NAME` 244 return 245 } 246 func (this_ *MysqlDialect) TableSelectSql(ownerName string, tableName string) (sql string, err error) { 247 sql = `SELECT TABLE_NAME,TABLE_COMMENT,TABLE_SCHEMA from information_schema.tables ` 248 sql += `WHERE 1=1 ` 249 if ownerName != "" { 250 sql += `AND TABLE_SCHEMA='` + ownerName + `' ` 251 } 252 sql += `AND TABLE_NAME='` + tableName + `' ` 253 sql += `ORDER BY TABLE_NAME` 254 return 255 } 256 func (this_ *MysqlDialect) TableCreateSql(ownerName string, table *TableModel) (sqlList []string, err error) { 257 sqlList = []string{} 258 259 createTableSql := `CREATE TABLE ` 260 261 if ownerName != "" { 262 createTableSql += this_.PackOwner(ownerName) + "." 263 } 264 createTableSql += this_.PackTable(table.Name) 265 266 createTableSql += `(` 267 createTableSql += "\n" 268 primaryKeys := "" 269 for _, column := range table.ColumnList { 270 var columnSql = this_.PackColumn(column.Name) 271 var columnType string 272 columnType, err = this_.FormatColumnType(column) 273 if err != nil { 274 return 275 } 276 277 columnSql += " " + columnType 278 279 if column.CharacterSetName != "" { 280 columnSql += ` CHARACTER SET ` + column.CharacterSetName 281 } 282 if column.Default != "" { 283 columnSql += " " + this_.FormatDefaultValue(column) 284 } 285 if column.NotNull { 286 columnSql += ` NOT NULL` 287 } 288 if column.Comment != "" { 289 columnSql += " COMMENT " + this_.PackValueForSql(nil, column.Comment) 290 } 291 292 if column.PrimaryKey { 293 primaryKeys += "" + column.Name + "," 294 } 295 createTableSql += "\t" + columnSql 296 createTableSql += ",\n" 297 } 298 if primaryKeys != "" { 299 primaryKeys = strings.TrimSuffix(primaryKeys, ",") 300 createTableSql += "\tPRIMARY KEY (" + this_.PackColumns(strings.Split(primaryKeys, ",")) + ")" 301 } 302 303 createTableSql = strings.TrimSuffix(createTableSql, ",\n") 304 createTableSql += "\n" 305 306 createTableSql += `)` 307 if table.CharacterSetName != "" { 308 createTableSql += ` DEFAULT CHARSET ` + table.CharacterSetName 309 } 310 311 sqlList = append(sqlList, createTableSql) 312 313 var sqlList_ []string 314 // 添加注释 315 if table.Comment != "" { 316 sqlList_, err = this_.TableCommentSql(ownerName, table.Name, table.Comment) 317 if err != nil { 318 return 319 } 320 sqlList = append(sqlList, sqlList_...) 321 } 322 323 for _, one := range table.IndexList { 324 sqlList_, err = this_.IndexAddSql(ownerName, table.Name, one) 325 if err != nil { 326 return 327 } 328 sqlList = append(sqlList, sqlList_...) 329 330 } 331 return 332 } 333 func (this_ *MysqlDialect) TableCommentSql(ownerName string, tableName string, comment string) (sqlList []string, err error) { 334 sql := "ALTER TABLE " 335 if ownerName != "" { 336 sql += this_.PackOwner(ownerName) + "." 337 } 338 sql += "" + this_.PackTable(tableName) 339 sql += " COMMENT " + this_.PackValueForSql(nil, comment) 340 341 sqlList = append(sqlList, sql) 342 return 343 } 344 func (this_ *MysqlDialect) TableRenameSql(ownerName string, oldTableName string, newTableName string) (sqlList []string, err error) { 345 sql := "ALTER TABLE " 346 if ownerName != "" { 347 sql += this_.PackOwner(ownerName) + "." 348 } 349 sql += "" + this_.PackTable(oldTableName) 350 sql += " RENAME AS " 351 sql += "" + this_.PackTable(newTableName) 352 sqlList = append(sqlList, sql) 353 return 354 } 355 func (this_ *MysqlDialect) TableDeleteSql(ownerName string, tableName string) (sqlList []string, err error) { 356 var sql string 357 sql = `DROP TABLE IF EXISTS ` 358 359 if ownerName != "" { 360 sql += this_.PackOwner(ownerName) + "." 361 } 362 sql += this_.PackTable(tableName) 363 364 sqlList = append(sqlList, sql) 365 return 366 } 367 func (this_ *MysqlDialect) ColumnModel(data map[string]interface{}) (column *ColumnModel, err error) { 368 if data == nil { 369 return 370 } 371 column = &ColumnModel{} 372 if data["COLUMN_NAME"] != nil { 373 column.Name = data["COLUMN_NAME"].(string) 374 } 375 if data["COLUMN_COMMENT"] != nil { 376 column.Comment = data["COLUMN_COMMENT"].(string) 377 } 378 if data["COLUMN_DEFAULT"] != nil { 379 column.Default = GetStringValue(data["COLUMN_DEFAULT"]) 380 if strings.Contains(strings.ToLower(column.Default), "current_timestamp") { 381 column.DefaultCurrentTimestamp = true 382 } else if strings.Contains(strings.ToLower(column.Default), "0000-00-00 00:00:00") { 383 column.DefaultCurrentTimestamp = true 384 } 385 } 386 if data["TABLE_NAME"] != nil { 387 column.TableName = data["TABLE_NAME"].(string) 388 } 389 if data["TABLE_SCHEMA"] != nil { 390 column.OwnerName = data["TABLE_SCHEMA"].(string) 391 } 392 if data["CHARACTER_SET_NAME"] != nil { 393 column.CharacterSetName = data["CHARACTER_SET_NAME"].(string) 394 } 395 if data["EXTRA"] != nil { 396 column.Extra = data["EXTRA"].(string) 397 if strings.Contains(strings.ToLower(column.Extra), "on update current_timestamp") { 398 column.OnUpdateCurrentTimestamp = true 399 } 400 } 401 402 if GetStringValue(data["IS_NULLABLE"]) == "NO" { 403 column.NotNull = true 404 } 405 var columnTypeInfo *ColumnTypeInfo 406 if data["COLUMN_TYPE"] != nil { 407 columnType := data["COLUMN_TYPE"].(string) 408 columnTypeInfo, column.Length, column.Decimal, err = this_.ToColumnTypeInfo(columnType) 409 if err != nil { 410 return 411 } 412 column.Type = columnTypeInfo.Name 413 414 if strings.EqualFold(column.Type, "SET") || strings.EqualFold(column.Type, "ENUM") { 415 if strings.Contains(columnType, "(") { 416 setStr := columnType[strings.Index(columnType, "(")+1 : strings.Index(columnType, ")")] 417 setStr = strings.ReplaceAll(setStr, "'", "") 418 column.Defaults = strings.Split(setStr, ",") 419 } 420 } 421 dataType := data["DATA_TYPE"].(string) 422 if !strings.EqualFold(dataType, column.Type) { 423 err = errors.New("column type [" + columnType + "] not eq data type [" + dataType + "]") 424 return 425 } 426 } 427 return 428 } 429 func (this_ *MysqlDialect) ColumnsSelectSql(ownerName string, tableName string) (sql string, err error) { 430 sql = `SELECT COLUMN_NAME,COLUMN_COMMENT,COLUMN_DEFAULT,EXTRA,TABLE_NAME,TABLE_SCHEMA,CHARACTER_SET_NAME,IS_NULLABLE,COLUMN_TYPE,DATA_TYPE from information_schema.columns ` 431 sql += `WHERE 1=1 ` 432 if ownerName != "" { 433 sql += `AND TABLE_SCHEMA='` + ownerName + `' ` 434 } 435 sql += `AND TABLE_NAME='` + tableName + `' ` 436 return 437 } 438 func (this_ *MysqlDialect) ColumnAddSql(ownerName string, tableName string, column *ColumnModel) (sqlList []string, err error) { 439 var columnType string 440 columnType, err = this_.FormatColumnType(column) 441 if err != nil { 442 return 443 } 444 445 sql := "ALTER TABLE " 446 if ownerName != "" { 447 sql += this_.PackOwner(ownerName) + "." 448 } 449 sql += "" + this_.PackTable(tableName) 450 sql += " ADD COLUMN " + this_.PackColumn(column.Name) 451 sql += " " + columnType 452 if column.Default != "" { 453 sql += " " + this_.FormatDefaultValue(column) 454 } 455 if column.NotNull { 456 sql += " NOT NULL" 457 } 458 sql += " COMMENT " + this_.PackValueForSql(nil, column.Comment) 459 if column.BeforeColumn != "" { 460 sql += " AFTER " + this_.PackColumn(column.BeforeColumn) 461 } 462 463 sqlList = append(sqlList, sql) 464 return 465 } 466 func (this_ *MysqlDialect) ColumnUpdateSql(ownerName string, tableName string, oldColumn *ColumnModel, newColumn *ColumnModel) (sqlList []string, err error) { 467 var columnType string 468 columnType, err = this_.FormatColumnType(newColumn) 469 if err != nil { 470 return 471 } 472 473 sql := "ALTER TABLE " 474 if ownerName != "" { 475 sql += this_.PackOwner(ownerName) + "." 476 } 477 sql += "" + this_.PackTable(tableName) 478 479 sql += " CHANGE COLUMN" 480 sql += " " + this_.PackColumn(oldColumn.Name) 481 sql += " " + this_.PackColumn(newColumn.Name) 482 sql += " " + columnType 483 484 if newColumn.Default == "" { 485 sql += " DEFAULT NULL" 486 } else { 487 sql += " " + this_.FormatDefaultValue(newColumn) 488 } 489 if newColumn.NotNull { 490 sql += " NOT NULL" 491 } 492 sql += " COMMENT " + this_.PackValueForSql(nil, newColumn.Comment) 493 if newColumn.BeforeColumn != "" { 494 sql += " AFTER " + this_.PackColumn(newColumn.BeforeColumn) 495 } 496 497 sqlList = append(sqlList, sql) 498 499 return 500 } 501 func (this_ *MysqlDialect) ColumnDeleteSql(ownerName string, tableName string, columnName string) (sqlList []string, err error) { 502 var sql string 503 sql = `ALTER TABLE ` 504 505 if ownerName != "" { 506 sql += this_.PackOwner(ownerName) + "." 507 } 508 sql += this_.PackTable(tableName) 509 510 sql += ` DROP COLUMN ` 511 sql += this_.PackColumn(columnName) 512 513 sqlList = append(sqlList, sql) 514 return 515 } 516 func (this_ *MysqlDialect) PrimaryKeyModel(data map[string]interface{}) (primaryKey *PrimaryKeyModel, err error) { 517 if data == nil { 518 return 519 } 520 primaryKey = &PrimaryKeyModel{} 521 if data["COLUMN_NAME"] != nil { 522 primaryKey.ColumnName = data["COLUMN_NAME"].(string) 523 } 524 if data["TABLE_NAME"] != nil { 525 primaryKey.TableName = data["TABLE_NAME"].(string) 526 } 527 if data["TABLE_SCHEMA"] != nil { 528 primaryKey.OwnerName = data["TABLE_SCHEMA"].(string) 529 } 530 return 531 } 532 func (this_ *MysqlDialect) PrimaryKeysSelectSql(ownerName string, tableName string) (sql string, err error) { 533 sql = `SELECT k.COLUMN_NAME,t.TABLE_NAME,t.TABLE_SCHEMA from information_schema.table_constraints t ` 534 sql += `JOIN information_schema.key_column_usage k USING (CONSTRAINT_NAME,TABLE_SCHEMA,TABLE_NAME) ` 535 sql += `WHERE 1=1 ` 536 if ownerName != "" { 537 sql += `AND t.TABLE_SCHEMA='` + ownerName + `' ` 538 } 539 sql += `AND t.TABLE_NAME='` + tableName + `' ` 540 sql += `AND t.CONSTRAINT_TYPE='PRIMARY KEY' ` 541 return 542 } 543 func (this_ *MysqlDialect) PrimaryKeyAddSql(ownerName string, tableName string, primaryKeys []string) (sqlList []string, err error) { 544 sql := "ALTER TABLE " 545 if ownerName != "" { 546 sql += this_.PackOwner(ownerName) + "." 547 } 548 sql += "" + this_.PackTable(tableName) 549 550 sql += ` ADD PRIMARY KEY ` 551 552 sql += "(" + this_.PackColumns(primaryKeys) + ")" 553 554 sqlList = append(sqlList, sql) 555 return 556 } 557 func (this_ *MysqlDialect) PrimaryKeyDeleteSql(ownerName string, tableName string) (sqlList []string, err error) { 558 sql := "ALTER TABLE " 559 if ownerName != "" { 560 sql += this_.PackOwner(ownerName) + "." 561 } 562 sql += "" + this_.PackTable(tableName) 563 564 sql += ` DROP PRIMARY KEY ` 565 566 sqlList = append(sqlList, sql) 567 return 568 } 569 570 func (this_ *MysqlDialect) IndexModel(data map[string]interface{}) (index *IndexModel, err error) { 571 if data == nil { 572 return 573 } 574 index = &IndexModel{} 575 if data["INDEX_NAME"] != nil { 576 index.Name = data["INDEX_NAME"].(string) 577 } 578 if data["COLUMN_NAME"] != nil { 579 index.ColumnName = data["COLUMN_NAME"].(string) 580 } 581 if data["INDEX_COMMENT"] != nil { 582 index.Comment = data["INDEX_COMMENT"].(string) 583 } 584 if GetStringValue(data["NON_UNIQUE"]) == "0" { 585 index.Type = "unique" 586 } 587 if data["TABLE_NAME"] != nil { 588 index.TableName = data["TABLE_NAME"].(string) 589 } 590 if data["TABLE_SCHEMA"] != nil { 591 index.OwnerName = data["TABLE_SCHEMA"].(string) 592 } 593 return 594 } 595 func (this_ *MysqlDialect) IndexesSelectSql(ownerName string, tableName string) (sql string, err error) { 596 sql = `SELECT INDEX_NAME,COLUMN_NAME,INDEX_COMMENT,NON_UNIQUE,TABLE_NAME,TABLE_SCHEMA from information_schema.statistics ` 597 sql += `WHERE 1=1 ` 598 if ownerName != "" { 599 sql += `AND TABLE_SCHEMA='` + ownerName + `' ` 600 } 601 sql += `AND TABLE_NAME='` + tableName + `' ` 602 sql += `AND INDEX_NAME NOT IN(` 603 sql += `SELECT t.CONSTRAINT_NAME from information_schema.table_constraints t ` 604 sql += `JOIN information_schema.key_column_usage k USING (CONSTRAINT_NAME,TABLE_SCHEMA,TABLE_NAME) ` 605 sql += `WHERE 1=1 ` 606 if ownerName != "" { 607 sql += `AND t.TABLE_SCHEMA='` + ownerName + `' ` 608 } 609 sql += `AND t.TABLE_NAME='` + tableName + `' ` 610 sql += `AND t.CONSTRAINT_TYPE='PRIMARY KEY' ` 611 sql += `) ` 612 return 613 } 614 615 // ALTER TABLE [${ownerName}.]${tableName} ADD ${'PRIMARY KEY' | 'UNIQUE' | 'INDEX'} ${indexName} (${columns}) [COMMENT '${indexCommend}'] 616 617 func (this_ *MysqlDialect) IndexAddSql(ownerName string, tableName string, index *IndexModel) (sqlList []string, err error) { 618 sql := "ALTER TABLE " 619 if ownerName != "" { 620 sql += this_.PackOwner(ownerName) + "." 621 } 622 sql += "" + this_.PackTable(tableName) 623 624 switch strings.ToUpper(index.Type) { 625 case "PRIMARY": 626 sql += " ADD PRIMARY KEY " 627 case "UNIQUE": 628 sql += " ADD UNIQUE " 629 case "FULLTEXT": 630 sql += " ADD FULLTEXT " 631 case "": 632 sql += " ADD INDEX " 633 default: 634 err = errors.New("dialect [" + this_.DialectType().Name + "] not support index type [" + index.Type + "]") 635 return 636 } 637 if index.Name != "" { 638 sql += "" + this_.PackColumn(index.Name) + " " 639 } 640 if len(index.Columns) > 0 { 641 sql += "(" + this_.PackColumns(index.Columns) + ")" 642 } 643 644 if index.Comment != "" { 645 sql += " COMMENT " + this_.PackValueForSql(nil, index.Comment) 646 } 647 648 sqlList = append(sqlList, sql) 649 return 650 } 651 652 // ALTER TABLE [${ownerName}.]${tableName} DROP INDEX ${indexName} 653 654 func (this_ *MysqlDialect) IndexDeleteSql(ownerName string, tableName string, indexName string) (sqlList []string, err error) { 655 sql := "ALTER TABLE " 656 if ownerName != "" { 657 sql += this_.PackOwner(ownerName) + "." 658 } 659 sql += "" + this_.PackTable(tableName) 660 661 sql += ` DROP INDEX ` 662 sql += "" + this_.PackColumn(indexName) 663 664 sqlList = append(sqlList, sql) 665 return 666 }