| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- package migrator
- import (
- "fmt"
- "strings"
- "github.com/go-xorm/xorm"
- )
- type Dialect interface {
- DriverName() string
- Quote(string) string
- AndStr() string
- AutoIncrStr() string
- OrStr() string
- EqStr() string
- ShowCreateNull() bool
- SqlType(col *Column) string
- SupportEngine() bool
- LikeStr() string
- Default(col *Column) string
- BooleanStr(bool) string
- DateTimeFunc(string) string
- CreateIndexSql(tableName string, index *Index) string
- CreateTableSql(table *Table) string
- AddColumnSql(tableName string, col *Column) string
- CopyTableData(sourceTable string, targetTable string, sourceCols []string, targetCols []string) string
- DropTable(tableName string) string
- DropIndexSql(tableName string, index *Index) string
- RenameTable(oldName string, newName string) string
- UpdateTableSql(tableName string, columns []*Column) string
- IndexCheckSql(tableName, indexName string) (string, []interface{})
- ColumnCheckSql(tableName, columnName string) (string, []interface{})
- ColString(*Column) string
- ColStringNoPk(*Column) string
- Limit(limit int64) string
- LimitOffset(limit int64, offset int64) string
- PreInsertId(table string, sess *xorm.Session) error
- PostInsertId(table string, sess *xorm.Session) error
- CleanDB() error
- NoOpSql() string
- IsUniqueConstraintViolation(err error) bool
- IsDeadlock(err error) bool
- }
- func NewDialect(engine *xorm.Engine) Dialect {
- name := engine.DriverName()
- switch name {
- case MYSQL:
- return NewMysqlDialect(engine)
- case SQLITE:
- return NewSqlite3Dialect(engine)
- case POSTGRES:
- return NewPostgresDialect(engine)
- }
- panic("Unsupported database type: " + name)
- }
- type BaseDialect struct {
- dialect Dialect
- engine *xorm.Engine
- driverName string
- }
- func (d *BaseDialect) DriverName() string {
- return d.driverName
- }
- func (b *BaseDialect) ShowCreateNull() bool {
- return true
- }
- func (b *BaseDialect) AndStr() string {
- return "AND"
- }
- func (b *BaseDialect) LikeStr() string {
- return "LIKE"
- }
- func (b *BaseDialect) OrStr() string {
- return "OR"
- }
- func (b *BaseDialect) EqStr() string {
- return "="
- }
- func (b *BaseDialect) Default(col *Column) string {
- return col.Default
- }
- func (db *BaseDialect) DateTimeFunc(value string) string {
- return value
- }
- func (b *BaseDialect) CreateTableSql(table *Table) string {
- sql := "CREATE TABLE IF NOT EXISTS "
- sql += b.dialect.Quote(table.Name) + " (\n"
- pkList := table.PrimaryKeys
- for _, col := range table.Columns {
- if col.IsPrimaryKey && len(pkList) == 1 {
- sql += col.String(b.dialect)
- } else {
- sql += col.StringNoPk(b.dialect)
- }
- sql = strings.TrimSpace(sql)
- sql += "\n, "
- }
- if len(pkList) > 1 {
- quotedCols := []string{}
- for _, col := range pkList {
- quotedCols = append(quotedCols, b.dialect.Quote(col))
- }
- sql += "PRIMARY KEY ( " + strings.Join(quotedCols, ",") + " ), "
- }
- sql = sql[:len(sql)-2] + ")"
- if b.dialect.SupportEngine() {
- sql += " ENGINE=InnoDB DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci"
- }
- sql += ";"
- return sql
- }
- func (db *BaseDialect) AddColumnSql(tableName string, col *Column) string {
- return fmt.Sprintf("alter table %s ADD COLUMN %s", db.dialect.Quote(tableName), col.StringNoPk(db.dialect))
- }
- func (db *BaseDialect) CreateIndexSql(tableName string, index *Index) string {
- quote := db.dialect.Quote
- var unique string
- if index.Type == UniqueIndex {
- unique = " UNIQUE"
- }
- idxName := index.XName(tableName)
- quotedCols := []string{}
- for _, col := range index.Cols {
- quotedCols = append(quotedCols, db.dialect.Quote(col))
- }
- return fmt.Sprintf("CREATE%s INDEX %v ON %v (%v);", unique, quote(idxName), quote(tableName), strings.Join(quotedCols, ","))
- }
- func (db *BaseDialect) QuoteColList(cols []string) string {
- var sourceColsSql = ""
- for _, col := range cols {
- sourceColsSql += db.dialect.Quote(col)
- sourceColsSql += "\n, "
- }
- return strings.TrimSuffix(sourceColsSql, "\n, ")
- }
- func (db *BaseDialect) CopyTableData(sourceTable string, targetTable string, sourceCols []string, targetCols []string) string {
- sourceColsSql := db.QuoteColList(sourceCols)
- targetColsSql := db.QuoteColList(targetCols)
- quote := db.dialect.Quote
- return fmt.Sprintf("INSERT INTO %s (%s) SELECT %s FROM %s", quote(targetTable), targetColsSql, sourceColsSql, quote(sourceTable))
- }
- func (db *BaseDialect) DropTable(tableName string) string {
- quote := db.dialect.Quote
- return fmt.Sprintf("DROP TABLE IF EXISTS %s", quote(tableName))
- }
- func (db *BaseDialect) RenameTable(oldName string, newName string) string {
- quote := db.dialect.Quote
- return fmt.Sprintf("ALTER TABLE %s RENAME TO %s", quote(oldName), quote(newName))
- }
- func (db *BaseDialect) ColumnCheckSql(tableName, columnName string) (string, []interface{}) {
- return "", nil
- }
- func (db *BaseDialect) DropIndexSql(tableName string, index *Index) string {
- quote := db.dialect.Quote
- name := index.XName(tableName)
- return fmt.Sprintf("DROP INDEX %v ON %s", quote(name), quote(tableName))
- }
- func (db *BaseDialect) UpdateTableSql(tableName string, columns []*Column) string {
- return "-- NOT REQUIRED"
- }
- func (db *BaseDialect) ColString(col *Column) string {
- sql := db.dialect.Quote(col.Name) + " "
- sql += db.dialect.SqlType(col) + " "
- if col.IsPrimaryKey {
- sql += "PRIMARY KEY "
- if col.IsAutoIncrement {
- sql += db.dialect.AutoIncrStr() + " "
- }
- }
- if db.dialect.ShowCreateNull() {
- if col.Nullable {
- sql += "NULL "
- } else {
- sql += "NOT NULL "
- }
- }
- if col.Default != "" {
- sql += "DEFAULT " + db.dialect.Default(col) + " "
- }
- return sql
- }
- func (db *BaseDialect) ColStringNoPk(col *Column) string {
- sql := db.dialect.Quote(col.Name) + " "
- sql += db.dialect.SqlType(col) + " "
- if db.dialect.ShowCreateNull() {
- if col.Nullable {
- sql += "NULL "
- } else {
- sql += "NOT NULL "
- }
- }
- if col.Default != "" {
- sql += "DEFAULT " + db.dialect.Default(col) + " "
- }
- return sql
- }
- func (db *BaseDialect) Limit(limit int64) string {
- return fmt.Sprintf(" LIMIT %d", limit)
- }
- func (db *BaseDialect) LimitOffset(limit int64, offset int64) string {
- return fmt.Sprintf(" LIMIT %d OFFSET %d", limit, offset)
- }
- func (db *BaseDialect) PreInsertId(table string, sess *xorm.Session) error {
- return nil
- }
- func (db *BaseDialect) PostInsertId(table string, sess *xorm.Session) error {
- return nil
- }
- func (db *BaseDialect) CleanDB() error {
- return nil
- }
- func (db *BaseDialect) NoOpSql() string {
- return "SELECT 0;"
- }
|