move database-specific code into dialects (#11884)
This commit is contained in:
committed by
Torkel Ödegaard
parent
27e1c67453
commit
1dfff74da9
@@ -15,48 +15,9 @@ type Column struct {
|
||||
}
|
||||
|
||||
func (col *Column) String(d Dialect) string {
|
||||
sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
|
||||
|
||||
sql += d.SqlType(col) + " "
|
||||
|
||||
if col.IsPrimaryKey {
|
||||
sql += "PRIMARY KEY "
|
||||
if col.IsAutoIncrement {
|
||||
sql += d.AutoIncrStr() + " "
|
||||
}
|
||||
}
|
||||
|
||||
if d.ShowCreateNull() {
|
||||
if col.Nullable {
|
||||
sql += "NULL "
|
||||
} else {
|
||||
sql += "NOT NULL "
|
||||
}
|
||||
}
|
||||
|
||||
if col.Default != "" {
|
||||
sql += "DEFAULT " + col.Default + " "
|
||||
}
|
||||
|
||||
return sql
|
||||
return d.ColString(col)
|
||||
}
|
||||
|
||||
func (col *Column) StringNoPk(d Dialect) string {
|
||||
sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
|
||||
|
||||
sql += d.SqlType(col) + " "
|
||||
|
||||
if d.ShowCreateNull() {
|
||||
if col.Nullable {
|
||||
sql += "NULL "
|
||||
} else {
|
||||
sql += "NOT NULL "
|
||||
}
|
||||
}
|
||||
|
||||
if col.Default != "" {
|
||||
sql += "DEFAULT " + d.Default(col) + " "
|
||||
}
|
||||
|
||||
return sql
|
||||
return d.ColStringNoPk(col)
|
||||
}
|
||||
|
||||
@@ -3,11 +3,12 @@ package migrator
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
)
|
||||
|
||||
type Dialect interface {
|
||||
DriverName() string
|
||||
QuoteStr() string
|
||||
Quote(string) string
|
||||
AndStr() string
|
||||
AutoIncrStr() string
|
||||
@@ -31,16 +32,29 @@ type Dialect interface {
|
||||
TableCheckSql(tableName string) (string, []interface{})
|
||||
RenameTable(oldName string, newName string) string
|
||||
UpdateTableSql(tableName string, columns []*Column) string
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func NewDialect(name string) Dialect {
|
||||
func NewDialect(engine *xorm.Engine) Dialect {
|
||||
name := engine.DriverName()
|
||||
switch name {
|
||||
case MYSQL:
|
||||
return NewMysqlDialect()
|
||||
return NewMysqlDialect(engine)
|
||||
case SQLITE:
|
||||
return NewSqlite3Dialect()
|
||||
return NewSqlite3Dialect(engine)
|
||||
case POSTGRES:
|
||||
return NewPostgresDialect()
|
||||
return NewPostgresDialect(engine)
|
||||
}
|
||||
|
||||
panic("Unsupported database type: " + name)
|
||||
@@ -48,6 +62,7 @@ func NewDialect(name string) Dialect {
|
||||
|
||||
type BaseDialect struct {
|
||||
dialect Dialect
|
||||
engine *xorm.Engine
|
||||
driverName string
|
||||
}
|
||||
|
||||
@@ -100,9 +115,12 @@ func (b *BaseDialect) CreateTableSql(table *Table) string {
|
||||
}
|
||||
|
||||
if len(pkList) > 1 {
|
||||
sql += "PRIMARY KEY ( "
|
||||
sql += b.dialect.Quote(strings.Join(pkList, b.dialect.Quote(",")))
|
||||
sql += " ), "
|
||||
quotedCols := []string{}
|
||||
for _, col := range pkList {
|
||||
quotedCols = append(quotedCols, b.dialect.Quote(col))
|
||||
}
|
||||
|
||||
sql += "PRIMARY KEY ( " + strings.Join(quotedCols, ",") + " ), "
|
||||
}
|
||||
|
||||
sql = sql[:len(sql)-2] + ")"
|
||||
@@ -127,9 +145,12 @@ func (db *BaseDialect) CreateIndexSql(tableName string, index *Index) string {
|
||||
|
||||
idxName := index.XName(tableName)
|
||||
|
||||
return fmt.Sprintf("CREATE%s INDEX %v ON %v (%v);", unique,
|
||||
quote(idxName), quote(tableName),
|
||||
quote(strings.Join(index.Cols, quote(","))))
|
||||
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 {
|
||||
@@ -168,3 +189,74 @@ func (db *BaseDialect) DropIndexSql(tableName string, index *Index) string {
|
||||
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;"
|
||||
}
|
||||
|
||||
@@ -24,37 +24,58 @@ func (m *MigrationBase) GetCondition() MigrationCondition {
|
||||
type RawSqlMigration struct {
|
||||
MigrationBase
|
||||
|
||||
sqlite string
|
||||
mysql string
|
||||
postgres string
|
||||
sql map[string]string
|
||||
}
|
||||
|
||||
func NewRawSqlMigration(sql string) *RawSqlMigration {
|
||||
m := &RawSqlMigration{}
|
||||
if sql != "" {
|
||||
m.Default(sql)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *RawSqlMigration) Sql(dialect Dialect) string {
|
||||
switch dialect.DriverName() {
|
||||
case MYSQL:
|
||||
return m.mysql
|
||||
case SQLITE:
|
||||
return m.sqlite
|
||||
case POSTGRES:
|
||||
return m.postgres
|
||||
if m.sql != nil {
|
||||
if val := m.sql[dialect.DriverName()]; val != "" {
|
||||
return val
|
||||
}
|
||||
|
||||
if val := m.sql["default"]; val != "" {
|
||||
return val
|
||||
}
|
||||
}
|
||||
|
||||
panic("db type not supported")
|
||||
return dialect.NoOpSql()
|
||||
}
|
||||
|
||||
func (m *RawSqlMigration) Set(dialect string, sql string) *RawSqlMigration {
|
||||
if m.sql == nil {
|
||||
m.sql = make(map[string]string)
|
||||
}
|
||||
|
||||
m.sql[dialect] = sql
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *RawSqlMigration) Default(sql string) *RawSqlMigration {
|
||||
return m.Set("default", sql)
|
||||
}
|
||||
|
||||
func (m *RawSqlMigration) Sqlite(sql string) *RawSqlMigration {
|
||||
m.sqlite = sql
|
||||
return m
|
||||
return m.Set(SQLITE, sql)
|
||||
}
|
||||
|
||||
func (m *RawSqlMigration) Mysql(sql string) *RawSqlMigration {
|
||||
m.mysql = sql
|
||||
return m
|
||||
return m.Set(MYSQL, sql)
|
||||
}
|
||||
|
||||
func (m *RawSqlMigration) Postgres(sql string) *RawSqlMigration {
|
||||
m.postgres = sql
|
||||
return m
|
||||
return m.Set(POSTGRES, sql)
|
||||
}
|
||||
|
||||
func (m *RawSqlMigration) Mssql(sql string) *RawSqlMigration {
|
||||
return m.Set(MSSQL, sql)
|
||||
}
|
||||
|
||||
type AddColumnMigration struct {
|
||||
|
||||
@@ -31,7 +31,7 @@ func NewMigrator(engine *xorm.Engine) *Migrator {
|
||||
mg.x = engine
|
||||
mg.Logger = log.New("migrator")
|
||||
mg.migrations = make([]Migration, 0)
|
||||
mg.dialect = NewDialect(mg.x.DriverName())
|
||||
mg.dialect = NewDialect(mg.x)
|
||||
return mg
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
package migrator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
)
|
||||
|
||||
type Mysql struct {
|
||||
BaseDialect
|
||||
}
|
||||
|
||||
func NewMysqlDialect() *Mysql {
|
||||
func NewMysqlDialect(engine *xorm.Engine) *Mysql {
|
||||
d := Mysql{}
|
||||
d.BaseDialect.dialect = &d
|
||||
d.BaseDialect.engine = engine
|
||||
d.BaseDialect.driverName = MYSQL
|
||||
return &d
|
||||
}
|
||||
@@ -24,10 +28,6 @@ func (db *Mysql) Quote(name string) string {
|
||||
return "`" + name + "`"
|
||||
}
|
||||
|
||||
func (db *Mysql) QuoteStr() string {
|
||||
return "`"
|
||||
}
|
||||
|
||||
func (db *Mysql) AutoIncrStr() string {
|
||||
return "AUTO_INCREMENT"
|
||||
}
|
||||
@@ -105,3 +105,23 @@ func (db *Mysql) UpdateTableSql(tableName string, columns []*Column) string {
|
||||
|
||||
return "ALTER TABLE " + db.Quote(tableName) + " " + strings.Join(statements, ", ") + ";"
|
||||
}
|
||||
|
||||
func (db *Mysql) CleanDB() error {
|
||||
tables, _ := db.engine.DBMetas()
|
||||
sess := db.engine.NewSession()
|
||||
defer sess.Close()
|
||||
|
||||
for _, table := range tables {
|
||||
if _, err := sess.Exec("set foreign_key_checks = 0"); err != nil {
|
||||
return fmt.Errorf("failed to disable foreign key checks")
|
||||
}
|
||||
if _, err := sess.Exec("drop table " + table.Name + " ;"); err != nil {
|
||||
return fmt.Errorf("failed to delete table: %v, err: %v", table.Name, err)
|
||||
}
|
||||
if _, err := sess.Exec("set foreign_key_checks = 1"); err != nil {
|
||||
return fmt.Errorf("failed to disable foreign key checks")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,15 +4,18 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
)
|
||||
|
||||
type Postgres struct {
|
||||
BaseDialect
|
||||
}
|
||||
|
||||
func NewPostgresDialect() *Postgres {
|
||||
func NewPostgresDialect(engine *xorm.Engine) *Postgres {
|
||||
d := Postgres{}
|
||||
d.BaseDialect.dialect = &d
|
||||
d.BaseDialect.engine = engine
|
||||
d.BaseDialect.driverName = POSTGRES
|
||||
return &d
|
||||
}
|
||||
@@ -25,10 +28,6 @@ func (db *Postgres) Quote(name string) string {
|
||||
return "\"" + name + "\""
|
||||
}
|
||||
|
||||
func (db *Postgres) QuoteStr() string {
|
||||
return "\""
|
||||
}
|
||||
|
||||
func (b *Postgres) LikeStr() string {
|
||||
return "ILIKE"
|
||||
}
|
||||
@@ -117,8 +116,23 @@ func (db *Postgres) UpdateTableSql(tableName string, columns []*Column) string {
|
||||
var statements = []string{}
|
||||
|
||||
for _, col := range columns {
|
||||
statements = append(statements, "ALTER "+db.QuoteStr()+col.Name+db.QuoteStr()+" TYPE "+db.SqlType(col))
|
||||
statements = append(statements, "ALTER "+db.Quote(col.Name)+" TYPE "+db.SqlType(col))
|
||||
}
|
||||
|
||||
return "ALTER TABLE " + db.Quote(tableName) + " " + strings.Join(statements, ", ") + ";"
|
||||
}
|
||||
|
||||
func (db *Postgres) CleanDB() error {
|
||||
sess := db.engine.NewSession()
|
||||
defer sess.Close()
|
||||
|
||||
if _, err := sess.Exec("DROP SCHEMA public CASCADE;"); err != nil {
|
||||
return fmt.Errorf("Failed to drop schema public")
|
||||
}
|
||||
|
||||
if _, err := sess.Exec("CREATE SCHEMA public;"); err != nil {
|
||||
return fmt.Errorf("Failed to create schema public")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
package migrator
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
)
|
||||
|
||||
type Sqlite3 struct {
|
||||
BaseDialect
|
||||
}
|
||||
|
||||
func NewSqlite3Dialect() *Sqlite3 {
|
||||
func NewSqlite3Dialect(engine *xorm.Engine) *Sqlite3 {
|
||||
d := Sqlite3{}
|
||||
d.BaseDialect.dialect = &d
|
||||
d.BaseDialect.engine = engine
|
||||
d.BaseDialect.driverName = SQLITE
|
||||
return &d
|
||||
}
|
||||
@@ -21,10 +26,6 @@ func (db *Sqlite3) Quote(name string) string {
|
||||
return "`" + name + "`"
|
||||
}
|
||||
|
||||
func (db *Sqlite3) QuoteStr() string {
|
||||
return "`"
|
||||
}
|
||||
|
||||
func (db *Sqlite3) AutoIncrStr() string {
|
||||
return "AUTOINCREMENT"
|
||||
}
|
||||
@@ -77,3 +78,7 @@ func (db *Sqlite3) DropIndexSql(tableName string, index *Index) string {
|
||||
idxName := index.XName(tableName)
|
||||
return fmt.Sprintf("DROP INDEX %v", quote(idxName))
|
||||
}
|
||||
|
||||
func (db *Sqlite3) CleanDB() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ const (
|
||||
POSTGRES = "postgres"
|
||||
SQLITE = "sqlite3"
|
||||
MYSQL = "mysql"
|
||||
MSSQL = "mssql"
|
||||
)
|
||||
|
||||
type Migration interface {
|
||||
|
||||
Reference in New Issue
Block a user