db/schema/builder.go
2023-04-12 15:58:25 +08:00

129 lines
2.7 KiB
Go

package schema
import (
"github.com/samber/lo"
"git.fsdpf.net/go/db"
)
type Builder struct {
Connection *db.Connection // The database connection instance
Grammar IGrammar // The schema grammar instance
}
func NewSchema(conn *db.Connection) *Builder {
var grammar IGrammar
switch conn.GetConfig().Driver {
case "mysql":
grammar = &MysqlGrammar{}
case "sqlite3":
grammar = &Sqlite3Grammar{}
}
return &Builder{
Connection: conn,
Grammar: grammar,
}
}
// 判断数据表是否存在
func (this *Builder) HasTable(table string) (bool, error) {
query := this.Grammar.CompileTableExists()
dbName := this.Connection.GetConfig().Database
count := 0
if _, err := this.Connection.Select(query, []any{table, dbName}, &count); err != nil || count == 0 {
return false, err
}
return true, nil
}
// 判断表字段是个存在
func (this *Builder) HasColumns(table string, columns ...string) (bool, error) {
if tColumns, err := this.GetColumnListing(table); err != nil {
return false, err
} else {
for _, col := range columns {
if !lo.Contains(tColumns, col) {
return false, nil
}
}
}
return true, nil
}
// 判断数据库列是否存在
func (this *Builder) GetColumnListing(table string) (columns []string, err error) {
query := this.Grammar.CompileColumnListing(table)
dbName := this.Connection.GetConfig().Database
items := []struct {
ID int `db:"id"`
Name string `db:"name"`
}{}
bindings := []any{table, dbName}
if this.Connection.GetConfig().Driver == "sqlite3" {
bindings = nil
}
if _, err := this.Connection.Select(query, bindings, &items); err != nil {
return nil, err
}
for _, item := range items {
columns = append(columns, item.Name)
}
return
}
// 修改表
func (this *Builder) Table(table string, cb func(*Blueprint)) error {
bp := this.createBlueprint(table)
cb(bp)
return this.Build(bp)
}
// 创建表
func (this *Builder) Create(table string, cb func(*Blueprint)) error {
bp := this.createBlueprint(table)
bp.Create()
cb(bp)
return this.Build(bp)
}
// 修改表名
func (this *Builder) Rename(from, to string) error {
bp := this.createBlueprint(from)
bp.Rename(to)
return this.Build(bp)
}
// 删除表
func (this *Builder) Drop(table string) error {
bp := this.createBlueprint(table)
bp.Drop()
return this.Build(bp)
}
// 删除表, 先判断再删除
func (this *Builder) DropIfExists(table string) error {
bp := this.createBlueprint(table)
bp.DropIfExists()
return this.Build(bp)
}
func (b *Builder) createBlueprint(table string) *Blueprint {
return NewBlueprint(table)
}
// Build execute the blueprint to build / modify the table
func (this *Builder) Build(bp *Blueprint) error {
return bp.Build(this.Connection, this.Grammar)
}