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) }