move database-specific code into dialects (#11884)

This commit is contained in:
Dan Cech
2018-05-10 16:54:21 +02:00
committed by Torkel Ödegaard
parent 27e1c67453
commit 1dfff74da9
32 changed files with 334 additions and 244 deletions
+2 -41
View File
@@ -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)
}
+103 -11
View File
@@ -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;"
}
+38 -17
View File
@@ -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 {
+1 -1
View File
@@ -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
}
+1
View File
@@ -9,6 +9,7 @@ const (
POSTGRES = "postgres"
SQLITE = "sqlite3"
MYSQL = "mysql"
MSSQL = "mssql"
)
type Migration interface {