| |
| package schema |
|
|
| import ( |
| "fmt" |
| "regexp" |
| "strings" |
| ) |
|
|
| var varcharRegex = regexp.MustCompile(`VARCHAR\(\d+\)`) |
|
|
| |
| type TableBuilder struct { |
| name string |
| columns []string |
| indexes []IndexDef |
| } |
|
|
| |
| type IndexDef struct { |
| Name string |
| SQL string |
| } |
|
|
| |
| func NewTable(name string) *TableBuilder { |
| return &TableBuilder{name: name} |
| } |
|
|
| |
| func (b *TableBuilder) Name() string { |
| return b.name |
| } |
|
|
| |
| func (b *TableBuilder) Column(def string) *TableBuilder { |
| b.columns = append(b.columns, def) |
| return b |
| } |
|
|
| |
| func (b *TableBuilder) Index(name, columns string) *TableBuilder { |
| b.indexes = append(b.indexes, IndexDef{ |
| Name: name, |
| SQL: fmt.Sprintf("CREATE INDEX %s ON %s(%s)", name, b.name, columns), |
| }) |
| return b |
| } |
|
|
| |
| func (b *TableBuilder) BuildMySQL() string { |
| sql := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s (\n\t%s\n) ;", |
| b.name, |
| strings.Join(b.columns, ",\n\t")) |
| return sql |
| } |
|
|
| |
| func (b *TableBuilder) BuildSQLite() string { |
| sqliteColumns := make([]string, len(b.columns)) |
| for i, col := range b.columns { |
| sqliteColumns[i] = mysqlToSQLite(col) |
| } |
|
|
| sql := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s (\n\t%s\n);", |
| b.name, |
| strings.Join(sqliteColumns, ",\n\t")) |
| return sql |
| } |
|
|
| |
| func mysqlToSQLite(mysqlCol string) string { |
| col := mysqlCol |
|
|
| |
| col = strings.ReplaceAll(col, "INT PRIMARY KEY AUTO_INCREMENT", "INTEGER PRIMARY KEY AUTOINCREMENT") |
| col = strings.ReplaceAll(col, "TINYINT", "INTEGER") |
| col = strings.ReplaceAll(col, "BIGINT", "INTEGER") |
|
|
| |
| col = replaceWord(col, "INT", "INTEGER") |
| col = strings.ReplaceAll(col, "DOUBLE", "REAL") |
|
|
| |
| col = replaceVarchar(col) |
|
|
| |
| col = strings.ReplaceAll(col, "UNIQUE KEY uk_channel_key", "UNIQUE") |
|
|
| return col |
| } |
|
|
| |
| func replaceWord(s, oldWord, newWord string) string { |
| words := strings.Fields(s) |
| for i, word := range words { |
| |
| cleanWord := strings.TrimRight(word, ",") |
| if cleanWord == oldWord { |
| words[i] = strings.Replace(word, oldWord, newWord, 1) |
| } |
| } |
| return strings.Join(words, " ") |
| } |
|
|
| |
| func replaceVarchar(s string) string { |
| return varcharRegex.ReplaceAllString(s, "TEXT") |
| } |
|
|
| |
| func (b *TableBuilder) GetIndexesMySQL() []IndexDef { |
| return b.indexes |
| } |
|
|
| |
| func (b *TableBuilder) GetIndexesSQLite() []IndexDef { |
| indexes := make([]IndexDef, len(b.indexes)) |
| for i, idx := range b.indexes { |
| indexes[i] = IndexDef{ |
| Name: idx.Name, |
| SQL: strings.Replace(idx.SQL, "CREATE INDEX", "CREATE INDEX IF NOT EXISTS", 1), |
| } |
| } |
| return indexes |
| } |
|
|