mirror of
https://github.com/ent/ent.git
synced 2026-03-05 19:35:23 +03:00
dialect/sql: remove all DDL builders that no longer used (#4369)
This commit is contained in:
@@ -38,12 +38,8 @@ type querierErr interface {
|
||||
// ColumnBuilder is a builder for column definition in table creation.
|
||||
type ColumnBuilder struct {
|
||||
Builder
|
||||
typ string // column type.
|
||||
name string // column name.
|
||||
attr string // extra attributes.
|
||||
modify bool // modify existing.
|
||||
fk *ForeignKeyBuilder // foreign-key constraint.
|
||||
check func(*Builder) // column checks.
|
||||
typ string // column type.
|
||||
name string // column name.
|
||||
}
|
||||
|
||||
// Column returns a new ColumnBuilder with the given name.
|
||||
@@ -57,189 +53,15 @@ func (c *ColumnBuilder) Type(t string) *ColumnBuilder {
|
||||
return c
|
||||
}
|
||||
|
||||
// Attr sets an extra attribute for the column, like UNIQUE or AUTO_INCREMENT.
|
||||
func (c *ColumnBuilder) Attr(attr string) *ColumnBuilder {
|
||||
if c.attr != "" && attr != "" {
|
||||
c.attr += " "
|
||||
}
|
||||
c.attr += attr
|
||||
return c
|
||||
}
|
||||
|
||||
// Constraint adds the CONSTRAINT clause to the ADD COLUMN statement in SQLite.
|
||||
func (c *ColumnBuilder) Constraint(fk *ForeignKeyBuilder) *ColumnBuilder {
|
||||
c.fk = fk
|
||||
return c
|
||||
}
|
||||
|
||||
// Check adds a CHECK clause to the ADD COLUMN statement.
|
||||
func (c *ColumnBuilder) Check(check func(*Builder)) *ColumnBuilder {
|
||||
c.check = check
|
||||
return c
|
||||
}
|
||||
|
||||
// Query returns query representation of a Column.
|
||||
func (c *ColumnBuilder) Query() (string, []any) {
|
||||
c.Ident(c.name)
|
||||
if c.typ != "" {
|
||||
if c.postgres() && c.modify {
|
||||
c.WriteString(" TYPE")
|
||||
}
|
||||
c.Pad().WriteString(c.typ)
|
||||
}
|
||||
if c.attr != "" {
|
||||
c.Pad().WriteString(c.attr)
|
||||
}
|
||||
if c.fk != nil {
|
||||
c.WriteString(" CONSTRAINT " + c.fk.symbol)
|
||||
c.Pad().Join(c.fk.ref)
|
||||
for _, action := range c.fk.actions {
|
||||
c.Pad().WriteString(action)
|
||||
}
|
||||
}
|
||||
if c.check != nil {
|
||||
c.WriteString(" CHECK ")
|
||||
c.Wrap(c.check)
|
||||
}
|
||||
return c.String(), c.args
|
||||
}
|
||||
|
||||
// TableBuilder is a query builder for `CREATE TABLE` statement.
|
||||
type TableBuilder struct {
|
||||
Builder
|
||||
name string // table name.
|
||||
exists bool // check existence.
|
||||
charset string // table charset.
|
||||
collation string // table collation.
|
||||
options string // table options.
|
||||
columns []Querier // table columns.
|
||||
primary []string // primary key.
|
||||
constraints []Querier // foreign keys and indices.
|
||||
checks []func(*Builder) // check constraints.
|
||||
}
|
||||
|
||||
// CreateTable returns a query builder for the `CREATE TABLE` statement.
|
||||
//
|
||||
// CreateTable("users").
|
||||
// Columns(
|
||||
// Column("id").Type("int").Attr("auto_increment"),
|
||||
// Column("name").Type("varchar(255)"),
|
||||
// ).
|
||||
// PrimaryKey("id")
|
||||
func CreateTable(name string) *TableBuilder { return &TableBuilder{name: name} }
|
||||
|
||||
// IfNotExists appends the `IF NOT EXISTS` clause to the `CREATE TABLE` statement.
|
||||
func (t *TableBuilder) IfNotExists() *TableBuilder {
|
||||
t.exists = true
|
||||
return t
|
||||
}
|
||||
|
||||
// Column appends the given column to the `CREATE TABLE` statement.
|
||||
func (t *TableBuilder) Column(c *ColumnBuilder) *TableBuilder {
|
||||
t.columns = append(t.columns, c)
|
||||
return t
|
||||
}
|
||||
|
||||
// Columns appends a list of columns to the builder.
|
||||
func (t *TableBuilder) Columns(columns ...*ColumnBuilder) *TableBuilder {
|
||||
t.columns = make([]Querier, 0, len(columns))
|
||||
for i := range columns {
|
||||
t.columns = append(t.columns, columns[i])
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// PrimaryKey adds a column to the primary-key constraint in the statement.
|
||||
func (t *TableBuilder) PrimaryKey(column ...string) *TableBuilder {
|
||||
t.primary = append(t.primary, column...)
|
||||
return t
|
||||
}
|
||||
|
||||
// ForeignKeys adds a list of foreign-keys to the statement (without constraints).
|
||||
func (t *TableBuilder) ForeignKeys(fks ...*ForeignKeyBuilder) *TableBuilder {
|
||||
queries := make([]Querier, len(fks))
|
||||
for i := range fks {
|
||||
// Erase the constraint symbol/name.
|
||||
fks[i].symbol = ""
|
||||
queries[i] = fks[i]
|
||||
}
|
||||
t.constraints = append(t.constraints, queries...)
|
||||
return t
|
||||
}
|
||||
|
||||
// Constraints adds a list of foreign-key constraints to the statement.
|
||||
func (t *TableBuilder) Constraints(fks ...*ForeignKeyBuilder) *TableBuilder {
|
||||
queries := make([]Querier, len(fks))
|
||||
for i := range fks {
|
||||
queries[i] = &Wrapper{"CONSTRAINT %s", fks[i]}
|
||||
}
|
||||
t.constraints = append(t.constraints, queries...)
|
||||
return t
|
||||
}
|
||||
|
||||
// Checks adds CHECK clauses to the CREATE TABLE statement.
|
||||
func (t *TableBuilder) Checks(checks ...func(*Builder)) *TableBuilder {
|
||||
t.checks = append(t.checks, checks...)
|
||||
return t
|
||||
}
|
||||
|
||||
// Charset appends the `CHARACTER SET` clause to the statement. MySQL only.
|
||||
func (t *TableBuilder) Charset(s string) *TableBuilder {
|
||||
t.charset = s
|
||||
return t
|
||||
}
|
||||
|
||||
// Collate appends the `COLLATE` clause to the statement. MySQL only.
|
||||
func (t *TableBuilder) Collate(s string) *TableBuilder {
|
||||
t.collation = s
|
||||
return t
|
||||
}
|
||||
|
||||
// Options appends additional options to the statement (MySQL only).
|
||||
func (t *TableBuilder) Options(s string) *TableBuilder {
|
||||
t.options = s
|
||||
return t
|
||||
}
|
||||
|
||||
// Query returns query representation of a `CREATE TABLE` statement.
|
||||
//
|
||||
// CREATE TABLE [IF NOT EXISTS] name
|
||||
//
|
||||
// (table definition)
|
||||
// [charset and collation]
|
||||
func (t *TableBuilder) Query() (string, []any) {
|
||||
t.WriteString("CREATE TABLE ")
|
||||
if t.exists {
|
||||
t.WriteString("IF NOT EXISTS ")
|
||||
}
|
||||
t.Ident(t.name)
|
||||
t.Wrap(func(b *Builder) {
|
||||
b.JoinComma(t.columns...)
|
||||
if len(t.primary) > 0 {
|
||||
b.Comma().WriteString("PRIMARY KEY")
|
||||
b.Wrap(func(b *Builder) {
|
||||
b.IdentComma(t.primary...)
|
||||
})
|
||||
}
|
||||
if len(t.constraints) > 0 {
|
||||
b.Comma().JoinComma(t.constraints...)
|
||||
}
|
||||
for _, check := range t.checks {
|
||||
check(b.Comma())
|
||||
}
|
||||
})
|
||||
if t.charset != "" {
|
||||
t.WriteString(" CHARACTER SET " + t.charset)
|
||||
}
|
||||
if t.collation != "" {
|
||||
t.WriteString(" COLLATE " + t.collation)
|
||||
}
|
||||
if t.options != "" {
|
||||
t.WriteString(" " + t.options)
|
||||
}
|
||||
return t.String(), t.args
|
||||
}
|
||||
|
||||
// ViewBuilder is a query builder for `CREATE VIEW` statement.
|
||||
type ViewBuilder struct {
|
||||
Builder
|
||||
@@ -314,417 +136,6 @@ func (v *ViewBuilder) Query() (string, []any) {
|
||||
return v.String(), v.args
|
||||
}
|
||||
|
||||
// DescribeBuilder is a query builder for `DESCRIBE` statement.
|
||||
type DescribeBuilder struct {
|
||||
Builder
|
||||
name string // table name.
|
||||
}
|
||||
|
||||
// Describe returns a query builder for the `DESCRIBE` statement.
|
||||
//
|
||||
// Describe("users")
|
||||
func Describe(name string) *DescribeBuilder { return &DescribeBuilder{name: name} }
|
||||
|
||||
// Query returns query representation of a `DESCRIBE` statement.
|
||||
func (t *DescribeBuilder) Query() (string, []any) {
|
||||
t.WriteString("DESCRIBE ")
|
||||
t.Ident(t.name)
|
||||
return t.String(), nil
|
||||
}
|
||||
|
||||
// TableAlter is a query builder for `ALTER TABLE` statement.
|
||||
type TableAlter struct {
|
||||
Builder
|
||||
name string // table to alter.
|
||||
Queries []Querier // columns and foreign-keys to add.
|
||||
}
|
||||
|
||||
// AlterTable returns a query builder for the `ALTER TABLE` statement.
|
||||
//
|
||||
// AlterTable("users").
|
||||
// AddColumn(Column("group_id").Type("int").Attr("UNIQUE")).
|
||||
// AddForeignKey(ForeignKey().Columns("group_id").
|
||||
// Reference(Reference().Table("groups").Columns("id")).OnDelete("CASCADE")),
|
||||
// )
|
||||
func AlterTable(name string) *TableAlter { return &TableAlter{name: name} }
|
||||
|
||||
// AddColumn appends the `ADD COLUMN` clause to the given `ALTER TABLE` statement.
|
||||
func (t *TableAlter) AddColumn(c *ColumnBuilder) *TableAlter {
|
||||
t.Queries = append(t.Queries, &Wrapper{"ADD COLUMN %s", c})
|
||||
return t
|
||||
}
|
||||
|
||||
// ModifyColumn appends the `MODIFY/ALTER COLUMN` clause to the given `ALTER TABLE` statement.
|
||||
func (t *TableAlter) ModifyColumn(c *ColumnBuilder) *TableAlter {
|
||||
switch {
|
||||
case t.postgres():
|
||||
c.modify = true
|
||||
t.Queries = append(t.Queries, &Wrapper{"ALTER COLUMN %s", c})
|
||||
default:
|
||||
t.Queries = append(t.Queries, &Wrapper{"MODIFY COLUMN %s", c})
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// RenameColumn appends the `RENAME COLUMN` clause to the given `ALTER TABLE` statement.
|
||||
func (t *TableAlter) RenameColumn(old, new string) *TableAlter {
|
||||
t.Queries = append(t.Queries, Raw(fmt.Sprintf("RENAME COLUMN %s TO %s", t.Quote(old), t.Quote(new))))
|
||||
return t
|
||||
}
|
||||
|
||||
// ModifyColumns calls ModifyColumn with each of the given builders.
|
||||
func (t *TableAlter) ModifyColumns(cs ...*ColumnBuilder) *TableAlter {
|
||||
for _, c := range cs {
|
||||
t.ModifyColumn(c)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// DropColumn appends the `DROP COLUMN` clause to the given `ALTER TABLE` statement.
|
||||
func (t *TableAlter) DropColumn(c *ColumnBuilder) *TableAlter {
|
||||
t.Queries = append(t.Queries, &Wrapper{"DROP COLUMN %s", c})
|
||||
return t
|
||||
}
|
||||
|
||||
// ChangeColumn appends the `CHANGE COLUMN` clause to the given `ALTER TABLE` statement.
|
||||
func (t *TableAlter) ChangeColumn(name string, c *ColumnBuilder) *TableAlter {
|
||||
prefix := fmt.Sprintf("CHANGE COLUMN %s", t.Quote(name))
|
||||
t.Queries = append(t.Queries, &Wrapper{prefix + " %s", c})
|
||||
return t
|
||||
}
|
||||
|
||||
// RenameIndex appends the `RENAME INDEX` clause to the given `ALTER TABLE` statement.
|
||||
func (t *TableAlter) RenameIndex(curr, new string) *TableAlter {
|
||||
t.Queries = append(t.Queries, Raw(fmt.Sprintf("RENAME INDEX %s TO %s", t.Quote(curr), t.Quote(new))))
|
||||
return t
|
||||
}
|
||||
|
||||
// DropIndex appends the `DROP INDEX` clause to the given `ALTER TABLE` statement.
|
||||
func (t *TableAlter) DropIndex(name string) *TableAlter {
|
||||
t.Queries = append(t.Queries, Raw(fmt.Sprintf("DROP INDEX %s", t.Quote(name))))
|
||||
return t
|
||||
}
|
||||
|
||||
// AddIndex appends the `ADD INDEX` clause to the given `ALTER TABLE` statement.
|
||||
func (t *TableAlter) AddIndex(idx *IndexBuilder) *TableAlter {
|
||||
b := &Builder{dialect: t.dialect}
|
||||
b.WriteString("ADD ")
|
||||
if idx.unique {
|
||||
b.WriteString("UNIQUE ")
|
||||
}
|
||||
b.WriteString("INDEX ")
|
||||
b.Ident(idx.name)
|
||||
b.Wrap(func(b *Builder) {
|
||||
b.IdentComma(idx.columns...)
|
||||
})
|
||||
t.Queries = append(t.Queries, b)
|
||||
return t
|
||||
}
|
||||
|
||||
// AddForeignKey adds a foreign key constraint to the `ALTER TABLE` statement.
|
||||
func (t *TableAlter) AddForeignKey(fk *ForeignKeyBuilder) *TableAlter {
|
||||
t.Queries = append(t.Queries, &Wrapper{"ADD CONSTRAINT %s", fk})
|
||||
return t
|
||||
}
|
||||
|
||||
// DropConstraint appends the `DROP CONSTRAINT` clause to the given `ALTER TABLE` statement.
|
||||
func (t *TableAlter) DropConstraint(ident string) *TableAlter {
|
||||
t.Queries = append(t.Queries, Raw(fmt.Sprintf("DROP CONSTRAINT %s", t.Quote(ident))))
|
||||
return t
|
||||
}
|
||||
|
||||
// DropForeignKey appends the `DROP FOREIGN KEY` clause to the given `ALTER TABLE` statement.
|
||||
func (t *TableAlter) DropForeignKey(ident string) *TableAlter {
|
||||
t.Queries = append(t.Queries, Raw(fmt.Sprintf("DROP FOREIGN KEY %s", t.Quote(ident))))
|
||||
return t
|
||||
}
|
||||
|
||||
// Query returns query representation of the `ALTER TABLE` statement.
|
||||
//
|
||||
// ALTER TABLE name
|
||||
// [alter_specification]
|
||||
func (t *TableAlter) Query() (string, []any) {
|
||||
t.WriteString("ALTER TABLE ")
|
||||
t.Ident(t.name)
|
||||
t.Pad()
|
||||
t.JoinComma(t.Queries...)
|
||||
return t.String(), t.args
|
||||
}
|
||||
|
||||
// IndexAlter is a query builder for `ALTER INDEX` statement.
|
||||
type IndexAlter struct {
|
||||
Builder
|
||||
name string // index to alter.
|
||||
Queries []Querier // alter options.
|
||||
}
|
||||
|
||||
// AlterIndex returns a query builder for the `ALTER INDEX` statement.
|
||||
//
|
||||
// AlterIndex("old_key").
|
||||
// Rename("new_key")
|
||||
func AlterIndex(name string) *IndexAlter { return &IndexAlter{name: name} }
|
||||
|
||||
// Rename appends the `RENAME TO` clause to the `ALTER INDEX` statement.
|
||||
func (i *IndexAlter) Rename(name string) *IndexAlter {
|
||||
i.Queries = append(i.Queries, Raw(fmt.Sprintf("RENAME TO %s", i.Quote(name))))
|
||||
return i
|
||||
}
|
||||
|
||||
// Query returns query representation of the `ALTER INDEX` statement.
|
||||
//
|
||||
// ALTER INDEX name
|
||||
// [alter_specification]
|
||||
func (i *IndexAlter) Query() (string, []any) {
|
||||
i.WriteString("ALTER INDEX ")
|
||||
i.Ident(i.name)
|
||||
i.Pad()
|
||||
i.JoinComma(i.Queries...)
|
||||
return i.String(), i.args
|
||||
}
|
||||
|
||||
// ForeignKeyBuilder is the builder for the foreign-key constraint clause.
|
||||
type ForeignKeyBuilder struct {
|
||||
Builder
|
||||
symbol string
|
||||
columns []string
|
||||
actions []string
|
||||
ref *ReferenceBuilder
|
||||
}
|
||||
|
||||
// ForeignKey returns a builder for the foreign-key constraint clause in create/alter table statements.
|
||||
//
|
||||
// ForeignKey().
|
||||
// Columns("group_id").
|
||||
// Reference(Reference().Table("groups").Columns("id")).
|
||||
// OnDelete("CASCADE")
|
||||
func ForeignKey(symbol ...string) *ForeignKeyBuilder {
|
||||
fk := &ForeignKeyBuilder{}
|
||||
if len(symbol) != 0 {
|
||||
fk.symbol = symbol[0]
|
||||
}
|
||||
return fk
|
||||
}
|
||||
|
||||
// Symbol sets the symbol of the foreign key.
|
||||
func (fk *ForeignKeyBuilder) Symbol(s string) *ForeignKeyBuilder {
|
||||
fk.symbol = s
|
||||
return fk
|
||||
}
|
||||
|
||||
// Columns sets the columns of the foreign key in the source table.
|
||||
func (fk *ForeignKeyBuilder) Columns(s ...string) *ForeignKeyBuilder {
|
||||
fk.columns = append(fk.columns, s...)
|
||||
return fk
|
||||
}
|
||||
|
||||
// Reference sets the reference clause.
|
||||
func (fk *ForeignKeyBuilder) Reference(r *ReferenceBuilder) *ForeignKeyBuilder {
|
||||
fk.ref = r
|
||||
return fk
|
||||
}
|
||||
|
||||
// OnDelete sets the on delete action for this constraint.
|
||||
func (fk *ForeignKeyBuilder) OnDelete(action string) *ForeignKeyBuilder {
|
||||
fk.actions = append(fk.actions, "ON DELETE "+action)
|
||||
return fk
|
||||
}
|
||||
|
||||
// OnUpdate sets the on delete action for this constraint.
|
||||
func (fk *ForeignKeyBuilder) OnUpdate(action string) *ForeignKeyBuilder {
|
||||
fk.actions = append(fk.actions, "ON UPDATE "+action)
|
||||
return fk
|
||||
}
|
||||
|
||||
// Query returns query representation of a foreign key constraint.
|
||||
func (fk *ForeignKeyBuilder) Query() (string, []any) {
|
||||
if fk.symbol != "" {
|
||||
fk.Ident(fk.symbol).Pad()
|
||||
}
|
||||
fk.WriteString("FOREIGN KEY")
|
||||
fk.Wrap(func(b *Builder) {
|
||||
b.IdentComma(fk.columns...)
|
||||
})
|
||||
fk.Pad().Join(fk.ref)
|
||||
for _, action := range fk.actions {
|
||||
fk.Pad().WriteString(action)
|
||||
}
|
||||
return fk.String(), fk.args
|
||||
}
|
||||
|
||||
// ReferenceBuilder is a builder for the reference clause in constraints. For example, in foreign key creation.
|
||||
type ReferenceBuilder struct {
|
||||
Builder
|
||||
table string // referenced table.
|
||||
columns []string // referenced columns.
|
||||
}
|
||||
|
||||
// Reference creates a reference builder for the reference_option clause.
|
||||
//
|
||||
// Reference().Table("groups").Columns("id")
|
||||
func Reference() *ReferenceBuilder { return &ReferenceBuilder{} }
|
||||
|
||||
// Table sets the referenced table.
|
||||
func (r *ReferenceBuilder) Table(s string) *ReferenceBuilder {
|
||||
r.table = s
|
||||
return r
|
||||
}
|
||||
|
||||
// Columns sets the columns of the referenced table.
|
||||
func (r *ReferenceBuilder) Columns(s ...string) *ReferenceBuilder {
|
||||
r.columns = append(r.columns, s...)
|
||||
return r
|
||||
}
|
||||
|
||||
// Query returns query representation of a reference clause.
|
||||
func (r *ReferenceBuilder) Query() (string, []any) {
|
||||
r.WriteString("REFERENCES ")
|
||||
r.Ident(r.table)
|
||||
r.Wrap(func(b *Builder) {
|
||||
b.IdentComma(r.columns...)
|
||||
})
|
||||
return r.String(), r.args
|
||||
}
|
||||
|
||||
// IndexBuilder is a builder for `CREATE INDEX` statement.
|
||||
type IndexBuilder struct {
|
||||
Builder
|
||||
name string
|
||||
unique bool
|
||||
exists bool
|
||||
table string
|
||||
method string
|
||||
columns []string
|
||||
}
|
||||
|
||||
// CreateIndex creates a builder for the `CREATE INDEX` statement.
|
||||
//
|
||||
// CreateIndex("index_name").
|
||||
// Unique().
|
||||
// Table("users").
|
||||
// Column("name")
|
||||
//
|
||||
// Or:
|
||||
//
|
||||
// CreateIndex("index_name").
|
||||
// Unique().
|
||||
// Table("users").
|
||||
// Columns("name", "age")
|
||||
func CreateIndex(name string) *IndexBuilder {
|
||||
return &IndexBuilder{name: name}
|
||||
}
|
||||
|
||||
// IfNotExists appends the `IF NOT EXISTS` clause to the `CREATE INDEX` statement.
|
||||
func (i *IndexBuilder) IfNotExists() *IndexBuilder {
|
||||
i.exists = true
|
||||
return i
|
||||
}
|
||||
|
||||
// Unique sets the index to be a unique index.
|
||||
func (i *IndexBuilder) Unique() *IndexBuilder {
|
||||
i.unique = true
|
||||
return i
|
||||
}
|
||||
|
||||
// Table defines the table for the index.
|
||||
func (i *IndexBuilder) Table(table string) *IndexBuilder {
|
||||
i.table = table
|
||||
return i
|
||||
}
|
||||
|
||||
// Using sets the method to create the index with.
|
||||
func (i *IndexBuilder) Using(method string) *IndexBuilder {
|
||||
i.method = method
|
||||
return i
|
||||
}
|
||||
|
||||
// Column appends a column to the column list for the index.
|
||||
func (i *IndexBuilder) Column(column string) *IndexBuilder {
|
||||
i.columns = append(i.columns, column)
|
||||
return i
|
||||
}
|
||||
|
||||
// Columns appends the given columns to the column list for the index.
|
||||
func (i *IndexBuilder) Columns(columns ...string) *IndexBuilder {
|
||||
i.columns = append(i.columns, columns...)
|
||||
return i
|
||||
}
|
||||
|
||||
// Query returns query representation of a reference clause.
|
||||
func (i *IndexBuilder) Query() (string, []any) {
|
||||
i.WriteString("CREATE ")
|
||||
if i.unique {
|
||||
i.WriteString("UNIQUE ")
|
||||
}
|
||||
i.WriteString("INDEX ")
|
||||
if i.exists {
|
||||
i.WriteString("IF NOT EXISTS ")
|
||||
}
|
||||
i.Ident(i.name)
|
||||
i.WriteString(" ON ")
|
||||
i.Ident(i.table)
|
||||
switch i.dialect {
|
||||
case dialect.Postgres:
|
||||
if i.method != "" {
|
||||
i.WriteString(" USING ").Ident(i.method)
|
||||
}
|
||||
i.Wrap(func(b *Builder) {
|
||||
b.IdentComma(i.columns...)
|
||||
})
|
||||
case dialect.MySQL:
|
||||
i.Wrap(func(b *Builder) {
|
||||
b.IdentComma(i.columns...)
|
||||
})
|
||||
if i.method != "" {
|
||||
i.WriteString(" USING " + i.method)
|
||||
}
|
||||
default:
|
||||
i.Wrap(func(b *Builder) {
|
||||
b.IdentComma(i.columns...)
|
||||
})
|
||||
}
|
||||
return i.String(), nil
|
||||
}
|
||||
|
||||
// DropIndexBuilder is a builder for `DROP INDEX` statement.
|
||||
type DropIndexBuilder struct {
|
||||
Builder
|
||||
name string
|
||||
table string
|
||||
}
|
||||
|
||||
// DropIndex creates a builder for the `DROP INDEX` statement.
|
||||
//
|
||||
// MySQL:
|
||||
//
|
||||
// DropIndex("index_name").
|
||||
// Table("users").
|
||||
//
|
||||
// SQLite/PostgreSQL:
|
||||
//
|
||||
// DropIndex("index_name")
|
||||
func DropIndex(name string) *DropIndexBuilder {
|
||||
return &DropIndexBuilder{name: name}
|
||||
}
|
||||
|
||||
// Table defines the table for the index.
|
||||
func (d *DropIndexBuilder) Table(table string) *DropIndexBuilder {
|
||||
d.table = table
|
||||
return d
|
||||
}
|
||||
|
||||
// Query returns query representation of a reference clause.
|
||||
//
|
||||
// DROP INDEX index_name [ON table_name]
|
||||
func (d *DropIndexBuilder) Query() (string, []any) {
|
||||
d.WriteString("DROP INDEX ")
|
||||
d.Ident(d.name)
|
||||
if d.table != "" {
|
||||
d.WriteString(" ON ")
|
||||
d.Ident(d.table)
|
||||
}
|
||||
return d.String(), nil
|
||||
}
|
||||
|
||||
// InsertBuilder is a builder for `INSERT INTO` statement.
|
||||
type InsertBuilder struct {
|
||||
Builder
|
||||
@@ -3990,31 +3401,6 @@ func (d *DialectBuilder) Expr(f func(*Builder)) Querier {
|
||||
return Expr(d.String(f))
|
||||
}
|
||||
|
||||
// Describe creates a DescribeBuilder for the configured dialect.
|
||||
//
|
||||
// Dialect(dialect.Postgres).
|
||||
// Describe("users")
|
||||
func (d *DialectBuilder) Describe(name string) *DescribeBuilder {
|
||||
b := Describe(name)
|
||||
b.SetDialect(d.dialect)
|
||||
return b
|
||||
}
|
||||
|
||||
// CreateTable creates a TableBuilder for the configured dialect.
|
||||
//
|
||||
// Dialect(dialect.Postgres).
|
||||
// CreateTable("users").
|
||||
// Columns(
|
||||
// Column("id").Type("int").Attr("auto_increment"),
|
||||
// Column("name").Type("varchar(255)"),
|
||||
// ).
|
||||
// PrimaryKey("id")
|
||||
func (d *DialectBuilder) CreateTable(name string) *TableBuilder {
|
||||
b := CreateTable(name)
|
||||
b.SetDialect(d.dialect)
|
||||
return b
|
||||
}
|
||||
|
||||
// CreateView creates a ViewBuilder for the configured dialect.
|
||||
//
|
||||
// t := Table("users")
|
||||
@@ -4031,32 +3417,6 @@ func (d *DialectBuilder) CreateView(name string) *ViewBuilder {
|
||||
return b
|
||||
}
|
||||
|
||||
// AlterTable creates a TableAlter for the configured dialect.
|
||||
//
|
||||
// Dialect(dialect.Postgres).
|
||||
// AlterTable("users").
|
||||
// AddColumn(Column("group_id").Type("int").Attr("UNIQUE")).
|
||||
// AddForeignKey(ForeignKey().Columns("group_id").
|
||||
// Reference(Reference().Table("groups").Columns("id")).
|
||||
// OnDelete("CASCADE"),
|
||||
// )
|
||||
func (d *DialectBuilder) AlterTable(name string) *TableAlter {
|
||||
b := AlterTable(name)
|
||||
b.SetDialect(d.dialect)
|
||||
return b
|
||||
}
|
||||
|
||||
// AlterIndex creates an IndexAlter for the configured dialect.
|
||||
//
|
||||
// Dialect(dialect.Postgres).
|
||||
// AlterIndex("old").
|
||||
// Rename("new")
|
||||
func (d *DialectBuilder) AlterIndex(name string) *IndexAlter {
|
||||
b := AlterIndex(name)
|
||||
b.SetDialect(d.dialect)
|
||||
return b
|
||||
}
|
||||
|
||||
// Column creates a ColumnBuilder for the configured dialect.
|
||||
//
|
||||
// Dialect(dialect.Postgres)..
|
||||
@@ -4140,29 +3500,6 @@ func (d *DialectBuilder) With(name string) *WithBuilder {
|
||||
return b
|
||||
}
|
||||
|
||||
// CreateIndex creates a IndexBuilder for the configured dialect.
|
||||
//
|
||||
// Dialect(dialect.Postgres).
|
||||
// CreateIndex("unique_name").
|
||||
// Unique().
|
||||
// Table("users").
|
||||
// Columns("first", "last")
|
||||
func (d *DialectBuilder) CreateIndex(name string) *IndexBuilder {
|
||||
b := CreateIndex(name)
|
||||
b.SetDialect(d.dialect)
|
||||
return b
|
||||
}
|
||||
|
||||
// DropIndex creates a DropIndexBuilder for the configured dialect.
|
||||
//
|
||||
// Dialect(dialect.Postgres).
|
||||
// DropIndex("name")
|
||||
func (d *DialectBuilder) DropIndex(name string) *DropIndexBuilder {
|
||||
b := DropIndex(name)
|
||||
b.SetDialect(d.dialect)
|
||||
return b
|
||||
}
|
||||
|
||||
func isAlias(s string) bool {
|
||||
return strings.Contains(s, " AS ") || strings.Contains(s, " as ")
|
||||
}
|
||||
|
||||
@@ -22,88 +22,6 @@ func TestBuilder(t *testing.T) {
|
||||
wantQuery string
|
||||
wantArgs []any
|
||||
}{
|
||||
{
|
||||
input: Describe("users"),
|
||||
wantQuery: "DESCRIBE `users`",
|
||||
},
|
||||
{
|
||||
input: CreateTable("users").
|
||||
Columns(
|
||||
Column("id").Type("int").Attr("auto_increment"),
|
||||
Column("name").Type("varchar(255)"),
|
||||
).
|
||||
PrimaryKey("id"),
|
||||
wantQuery: "CREATE TABLE `users`(`id` int auto_increment, `name` varchar(255), PRIMARY KEY(`id`))",
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).CreateTable("users").
|
||||
Columns(
|
||||
Column("id").Type("serial").Attr("PRIMARY KEY"),
|
||||
Column("name").Type("varchar"),
|
||||
),
|
||||
wantQuery: `CREATE TABLE "users"("id" serial PRIMARY KEY, "name" varchar)`,
|
||||
},
|
||||
{
|
||||
input: CreateTable("users").
|
||||
Columns(
|
||||
Column("id").Type("int").Attr("auto_increment"),
|
||||
Column("name").Type("varchar(255)"),
|
||||
).
|
||||
PrimaryKey("id").
|
||||
Charset("utf8mb4"),
|
||||
wantQuery: "CREATE TABLE `users`(`id` int auto_increment, `name` varchar(255), PRIMARY KEY(`id`)) CHARACTER SET utf8mb4",
|
||||
},
|
||||
{
|
||||
input: CreateTable("users").
|
||||
Columns(
|
||||
Column("id").Type("int").Attr("auto_increment"),
|
||||
Column("name").Type("varchar(255)"),
|
||||
).
|
||||
PrimaryKey("id").
|
||||
Charset("utf8mb4").
|
||||
Collate("utf8mb4_general_ci").
|
||||
Options("ENGINE=InnoDB"),
|
||||
wantQuery: "CREATE TABLE `users`(`id` int auto_increment, `name` varchar(255), PRIMARY KEY(`id`)) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ENGINE=InnoDB",
|
||||
},
|
||||
{
|
||||
input: CreateTable("users").
|
||||
IfNotExists().
|
||||
Columns(
|
||||
Column("id").Type("int").Attr("auto_increment"),
|
||||
).
|
||||
PrimaryKey("id", "name"),
|
||||
wantQuery: "CREATE TABLE IF NOT EXISTS `users`(`id` int auto_increment, PRIMARY KEY(`id`, `name`))",
|
||||
},
|
||||
{
|
||||
input: CreateTable("users").
|
||||
IfNotExists().
|
||||
Columns(
|
||||
Column("id").Type("int").Attr("auto_increment"),
|
||||
Column("card_id").Type("int"),
|
||||
Column("doc").Type("longtext").Check(func(b *Builder) {
|
||||
b.WriteString("JSON_VALID(").Ident("doc").WriteByte(')')
|
||||
}),
|
||||
).
|
||||
PrimaryKey("id", "name").
|
||||
ForeignKeys(ForeignKey().Columns("card_id").
|
||||
Reference(Reference().Table("cards").Columns("id")).OnDelete("SET NULL")).
|
||||
Checks(func(b *Builder) {
|
||||
b.WriteString("CONSTRAINT ").Ident("valid_card").WriteString(" CHECK (").Ident("card_id").WriteString(" > 0)")
|
||||
}),
|
||||
wantQuery: "CREATE TABLE IF NOT EXISTS `users`(`id` int auto_increment, `card_id` int, `doc` longtext CHECK (JSON_VALID(`doc`)), PRIMARY KEY(`id`, `name`), FOREIGN KEY(`card_id`) REFERENCES `cards`(`id`) ON DELETE SET NULL, CONSTRAINT `valid_card` CHECK (`card_id` > 0))",
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).CreateTable("users").
|
||||
IfNotExists().
|
||||
Columns(
|
||||
Column("id").Type("serial"),
|
||||
Column("card_id").Type("int"),
|
||||
).
|
||||
PrimaryKey("id", "name").
|
||||
ForeignKeys(ForeignKey().Columns("card_id").
|
||||
Reference(Reference().Table("cards").Columns("id")).OnDelete("SET NULL")),
|
||||
wantQuery: `CREATE TABLE IF NOT EXISTS "users"("id" serial, "card_id" int, PRIMARY KEY("id", "name"), FOREIGN KEY("card_id") REFERENCES "cards"("id") ON DELETE SET NULL)`,
|
||||
},
|
||||
{
|
||||
input: CreateView("clean_users").
|
||||
Columns(
|
||||
@@ -129,125 +47,6 @@ func TestBuilder(t *testing.T) {
|
||||
As(Select("id", "name").From(Table("users"))),
|
||||
wantQuery: "CREATE VIEW `schema`.`clean_users` AS SELECT `id`, `name` FROM `users`",
|
||||
},
|
||||
{
|
||||
input: AlterTable("users").
|
||||
AddColumn(Column("group_id").Type("int").Attr("UNIQUE")).
|
||||
AddForeignKey(ForeignKey().Columns("group_id").
|
||||
Reference(Reference().Table("groups").Columns("id")).
|
||||
OnDelete("CASCADE"),
|
||||
),
|
||||
wantQuery: "ALTER TABLE `users` ADD COLUMN `group_id` int UNIQUE, ADD CONSTRAINT FOREIGN KEY(`group_id`) REFERENCES `groups`(`id`) ON DELETE CASCADE",
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).AlterTable("users").
|
||||
AddColumn(Column("group_id").Type("int").Attr("UNIQUE")).
|
||||
AddForeignKey(ForeignKey("constraint").Columns("group_id").
|
||||
Reference(Reference().Table("groups").Columns("id")).
|
||||
OnDelete("CASCADE"),
|
||||
),
|
||||
wantQuery: `ALTER TABLE "users" ADD COLUMN "group_id" int UNIQUE, ADD CONSTRAINT "constraint" FOREIGN KEY("group_id") REFERENCES "groups"("id") ON DELETE CASCADE`,
|
||||
},
|
||||
{
|
||||
input: AlterTable("users").
|
||||
AddColumn(Column("group_id").Type("int").Attr("UNIQUE")).
|
||||
AddForeignKey(ForeignKey().Columns("group_id").
|
||||
Reference(Reference().Table("groups").Columns("id")),
|
||||
),
|
||||
wantQuery: "ALTER TABLE `users` ADD COLUMN `group_id` int UNIQUE, ADD CONSTRAINT FOREIGN KEY(`group_id`) REFERENCES `groups`(`id`)",
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).AlterTable("users").
|
||||
AddColumn(Column("group_id").Type("int").Attr("UNIQUE")).
|
||||
AddForeignKey(ForeignKey().Columns("group_id").
|
||||
Reference(Reference().Table("groups").Columns("id")),
|
||||
),
|
||||
wantQuery: `ALTER TABLE "users" ADD COLUMN "group_id" int UNIQUE, ADD CONSTRAINT FOREIGN KEY("group_id") REFERENCES "groups"("id")`,
|
||||
},
|
||||
{
|
||||
input: AlterTable("users").
|
||||
AddColumn(Column("age").Type("int")).
|
||||
AddColumn(Column("name").Type("varchar(255)")),
|
||||
wantQuery: "ALTER TABLE `users` ADD COLUMN `age` int, ADD COLUMN `name` varchar(255)",
|
||||
},
|
||||
{
|
||||
input: AlterTable("users").
|
||||
DropForeignKey("users_parent_id"),
|
||||
wantQuery: "ALTER TABLE `users` DROP FOREIGN KEY `users_parent_id`",
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).AlterTable("users").
|
||||
AddColumn(Column("age").Type("int")).
|
||||
AddColumn(Column("name").Type("varchar(255)")).
|
||||
DropConstraint("users_nickname_key"),
|
||||
wantQuery: `ALTER TABLE "users" ADD COLUMN "age" int, ADD COLUMN "name" varchar(255), DROP CONSTRAINT "users_nickname_key"`,
|
||||
},
|
||||
{
|
||||
input: AlterTable("users").
|
||||
AddForeignKey(ForeignKey().Columns("group_id").
|
||||
Reference(Reference().Table("groups").Columns("id")),
|
||||
).
|
||||
AddForeignKey(ForeignKey().Columns("location_id").
|
||||
Reference(Reference().Table("locations").Columns("id")),
|
||||
),
|
||||
wantQuery: "ALTER TABLE `users` ADD CONSTRAINT FOREIGN KEY(`group_id`) REFERENCES `groups`(`id`), ADD CONSTRAINT FOREIGN KEY(`location_id`) REFERENCES `locations`(`id`)",
|
||||
},
|
||||
{
|
||||
input: AlterTable("users").
|
||||
ModifyColumn(Column("age").Type("int")),
|
||||
wantQuery: "ALTER TABLE `users` MODIFY COLUMN `age` int",
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).AlterTable("users").
|
||||
ModifyColumn(Column("age").Type("int")),
|
||||
wantQuery: `ALTER TABLE "users" ALTER COLUMN "age" TYPE int`,
|
||||
},
|
||||
{
|
||||
input: AlterTable("users").
|
||||
ModifyColumn(Column("age").Type("int")).
|
||||
DropColumn(Column("name")),
|
||||
wantQuery: "ALTER TABLE `users` MODIFY COLUMN `age` int, DROP COLUMN `name`",
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).AlterTable("users").
|
||||
ModifyColumn(Column("age").Type("int")).
|
||||
DropColumn(Column("name")),
|
||||
wantQuery: `ALTER TABLE "users" ALTER COLUMN "age" TYPE int, DROP COLUMN "name"`,
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).AlterTable("users").
|
||||
ModifyColumn(Column("age").Type("int")).
|
||||
ModifyColumn(Column("age").Attr("SET NOT NULL")).
|
||||
ModifyColumn(Column("name").Attr("DROP NOT NULL")),
|
||||
wantQuery: `ALTER TABLE "users" ALTER COLUMN "age" TYPE int, ALTER COLUMN "age" SET NOT NULL, ALTER COLUMN "name" DROP NOT NULL`,
|
||||
},
|
||||
{
|
||||
input: AlterTable("users").
|
||||
ChangeColumn("old_age", Column("age").Type("int")),
|
||||
wantQuery: "ALTER TABLE `users` CHANGE COLUMN `old_age` `age` int",
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).AlterTable("users").
|
||||
AddColumn(Column("boring").Type("varchar")).
|
||||
ModifyColumn(Column("age").Type("int")).
|
||||
DropColumn(Column("name")),
|
||||
wantQuery: `ALTER TABLE "users" ADD COLUMN "boring" varchar, ALTER COLUMN "age" TYPE int, DROP COLUMN "name"`,
|
||||
},
|
||||
{
|
||||
input: AlterTable("users").RenameIndex("old", "new"),
|
||||
wantQuery: "ALTER TABLE `users` RENAME INDEX `old` TO `new`",
|
||||
},
|
||||
{
|
||||
input: AlterTable("users").
|
||||
DropIndex("old").
|
||||
AddIndex(CreateIndex("new1").Columns("c1", "c2")).
|
||||
AddIndex(CreateIndex("new2").Columns("c1", "c2").Unique()),
|
||||
wantQuery: "ALTER TABLE `users` DROP INDEX `old`, ADD INDEX `new1`(`c1`, `c2`), ADD UNIQUE INDEX `new2`(`c1`, `c2`)",
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).AlterIndex("old").
|
||||
Rename("new"),
|
||||
wantQuery: `ALTER INDEX "old" RENAME TO "new"`,
|
||||
},
|
||||
{
|
||||
input: Insert("users").Columns("age").Values(1),
|
||||
wantQuery: "INSERT INTO `users` (`age`) VALUES (?)",
|
||||
@@ -1522,82 +1321,12 @@ func TestBuilder(t *testing.T) {
|
||||
wantQuery: `SELECT * FROM "users" WHERE "name" = $1 AND ("users"."id", "users"."name") < ($2, $3)`,
|
||||
wantArgs: []any{"Ariel", 1, "Ariel"},
|
||||
},
|
||||
{
|
||||
input: CreateIndex("name_index").Table("users").Column("name"),
|
||||
wantQuery: "CREATE INDEX `name_index` ON `users`(`name`)",
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).
|
||||
CreateIndex("name_index").
|
||||
Table("users").
|
||||
Column("name"),
|
||||
wantQuery: `CREATE INDEX "name_index" ON "users"("name")`,
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).
|
||||
CreateIndex("name_index").
|
||||
IfNotExists().
|
||||
Table("users").
|
||||
Column("name"),
|
||||
wantQuery: `CREATE INDEX IF NOT EXISTS "name_index" ON "users"("name")`,
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).
|
||||
CreateIndex("name_index").
|
||||
IfNotExists().
|
||||
Table("users").
|
||||
Using("gin").
|
||||
Column("name"),
|
||||
wantQuery: `CREATE INDEX IF NOT EXISTS "name_index" ON "users" USING "gin"("name")`,
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.MySQL).
|
||||
CreateIndex("name_index").
|
||||
IfNotExists().
|
||||
Table("users").
|
||||
Using("HASH").
|
||||
Column("name"),
|
||||
wantQuery: "CREATE INDEX IF NOT EXISTS `name_index` ON `users`(`name`) USING HASH",
|
||||
},
|
||||
{
|
||||
input: CreateIndex("unique_name").Unique().Table("users").Columns("first", "last"),
|
||||
wantQuery: "CREATE UNIQUE INDEX `unique_name` ON `users`(`first`, `last`)",
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).
|
||||
CreateIndex("unique_name").
|
||||
Unique().
|
||||
Table("users").
|
||||
Columns("first", "last"),
|
||||
wantQuery: `CREATE UNIQUE INDEX "unique_name" ON "users"("first", "last")`,
|
||||
},
|
||||
{
|
||||
input: DropIndex("name_index"),
|
||||
wantQuery: "DROP INDEX `name_index`",
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).
|
||||
DropIndex("name_index"),
|
||||
wantQuery: `DROP INDEX "name_index"`,
|
||||
},
|
||||
{
|
||||
input: DropIndex("name_index").Table("users"),
|
||||
wantQuery: "DROP INDEX `name_index` ON `users`",
|
||||
},
|
||||
{
|
||||
input: Select().
|
||||
From(Table("pragma_table_info('t1')").Unquote()).
|
||||
OrderBy("pk"),
|
||||
wantQuery: "SELECT * FROM pragma_table_info('t1') ORDER BY `pk`",
|
||||
},
|
||||
{
|
||||
input: AlterTable("users").
|
||||
AddColumn(Column("spouse").Type("integer").
|
||||
Constraint(ForeignKey("user_spouse").
|
||||
Reference(Reference().Table("users").Columns("id")).
|
||||
OnDelete("SET NULL"))),
|
||||
wantQuery: "ALTER TABLE `users` ADD COLUMN `spouse` integer CONSTRAINT user_spouse REFERENCES `users`(`id`) ON DELETE SET NULL",
|
||||
},
|
||||
{
|
||||
input: Dialect(dialect.Postgres).
|
||||
Select("*").
|
||||
|
||||
@@ -430,28 +430,6 @@ type ForeignKey struct {
|
||||
OnDelete ReferenceOption // action on delete.
|
||||
}
|
||||
|
||||
// DSL returns a default DSL query for a foreign-key.
|
||||
func (fk ForeignKey) DSL() *sql.ForeignKeyBuilder {
|
||||
cols := make([]string, len(fk.Columns))
|
||||
refs := make([]string, len(fk.RefColumns))
|
||||
for i, c := range fk.Columns {
|
||||
cols[i] = c.Name
|
||||
}
|
||||
for i, c := range fk.RefColumns {
|
||||
refs[i] = c.Name
|
||||
}
|
||||
dsl := sql.ForeignKey().Symbol(fk.Symbol).
|
||||
Columns(cols...).
|
||||
Reference(sql.Reference().Table(fk.RefTable.Name).Columns(refs...))
|
||||
if action := string(fk.OnDelete); action != "" {
|
||||
dsl.OnDelete(action)
|
||||
}
|
||||
if action := string(fk.OnUpdate); action != "" {
|
||||
dsl.OnUpdate(action)
|
||||
}
|
||||
return dsl
|
||||
}
|
||||
|
||||
// ReferenceOption for constraint actions.
|
||||
type ReferenceOption string
|
||||
|
||||
@@ -479,24 +457,6 @@ type Index struct {
|
||||
realname string // real name in the database (Postgres only).
|
||||
}
|
||||
|
||||
// Builder returns the query builder for index creation. The DSL is identical in all dialects.
|
||||
func (i *Index) Builder(table string) *sql.IndexBuilder {
|
||||
idx := sql.CreateIndex(i.Name).Table(table)
|
||||
if i.Unique {
|
||||
idx.Unique()
|
||||
}
|
||||
for _, c := range i.Columns {
|
||||
idx.Column(c.Name)
|
||||
}
|
||||
return idx
|
||||
}
|
||||
|
||||
// DropBuilder returns the query builder for the drop index.
|
||||
func (i *Index) DropBuilder(table string) *sql.DropIndexBuilder {
|
||||
idx := sql.DropIndex(i.Name).Table(table)
|
||||
return idx
|
||||
}
|
||||
|
||||
// Indexes used for scanning all sql.Rows into a list of indexes, because
|
||||
// multiple sql rows can represent the same index (multi-columns indexes).
|
||||
type Indexes []*Index
|
||||
|
||||
Reference in New Issue
Block a user