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  }