mirror of
https://github.com/ent/ent.git
synced 2026-05-24 09:31:56 +03:00
ent: support schema view (#4157)
This commit is contained in:
@@ -572,7 +572,11 @@ func (a *Atlas) StateReader(tables ...*Table) migrate.StateReaderFunc {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &schema.Realm{Schemas: []*schema.Schema{{Tables: ts}}}, nil
|
||||
vs, err := a.views(tables)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &schema.Realm{Schemas: []*schema.Schema{{Tables: ts, Views: vs}}}, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -878,8 +882,14 @@ func (d *db) ExecContext(ctx context.Context, query string, args ...any) (sql.Re
|
||||
|
||||
// tables converts an Ent table slice to an atlas table slice
|
||||
func (a *Atlas) tables(tables []*Table) ([]*schema.Table, error) {
|
||||
ts := make([]*schema.Table, len(tables))
|
||||
for i, et := range tables {
|
||||
var (
|
||||
byT = make(map[*Table]*schema.Table)
|
||||
ts = make([]*schema.Table, 0, len(tables))
|
||||
)
|
||||
for _, et := range tables {
|
||||
if et.View {
|
||||
continue
|
||||
}
|
||||
at := schema.NewTable(et.Name)
|
||||
if et.Comment != "" {
|
||||
at.SetComment(et.Comment)
|
||||
@@ -898,10 +908,14 @@ func (a *Atlas) tables(tables []*Table) ([]*schema.Table, error) {
|
||||
if err := a.aIndexes(et, at); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ts[i] = at
|
||||
ts = append(ts, at)
|
||||
byT[et] = at
|
||||
}
|
||||
for i, t1 := range tables {
|
||||
t2 := ts[i]
|
||||
for _, t1 := range tables {
|
||||
if t1.View {
|
||||
continue
|
||||
}
|
||||
t2 := byT[t1]
|
||||
for _, fk1 := range t1.ForeignKeys {
|
||||
fk2 := schema.NewForeignKey(fk1.Symbol).
|
||||
SetTable(t2).
|
||||
@@ -938,6 +952,30 @@ func (a *Atlas) tables(tables []*Table) ([]*schema.Table, error) {
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
// tables converts an Ent table slice to an atlas table slice
|
||||
func (a *Atlas) views(tables []*Table) ([]*schema.View, error) {
|
||||
vs := make([]*schema.View, 0, len(tables))
|
||||
for _, et := range tables {
|
||||
// Not a view, or the view defined externally.
|
||||
if !et.View || et.Annotation == nil || (et.Annotation.ViewAs == "" && et.Annotation.ViewFor[a.dialect] == "") {
|
||||
continue
|
||||
}
|
||||
def := et.Annotation.ViewFor[a.dialect]
|
||||
if def == "" {
|
||||
def = et.Annotation.ViewAs
|
||||
}
|
||||
av := schema.NewView(et.Name, def)
|
||||
if et.Comment != "" {
|
||||
av.SetComment(et.Comment)
|
||||
}
|
||||
if err := a.aVColumns(et, av); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vs = append(vs, av)
|
||||
}
|
||||
return vs, nil
|
||||
}
|
||||
|
||||
func (a *Atlas) aColumns(et *Table, at *schema.Table) error {
|
||||
for _, c1 := range et.Columns {
|
||||
c2 := schema.NewColumn(c1.Name).
|
||||
@@ -965,6 +1003,27 @@ func (a *Atlas) aColumns(et *Table, at *schema.Table) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Atlas) aVColumns(et *Table, at *schema.View) error {
|
||||
for _, c1 := range et.Columns {
|
||||
c2 := schema.NewColumn(c1.Name).
|
||||
SetNull(c1.Nullable)
|
||||
if c1.Collation != "" {
|
||||
c2.SetCollation(c1.Collation)
|
||||
}
|
||||
if c1.Comment != "" {
|
||||
c2.SetComment(c1.Comment)
|
||||
}
|
||||
if err := a.sqlDialect.atTypeC(c1, c2); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := a.atDefault(c1, c2); err != nil {
|
||||
return err
|
||||
}
|
||||
at.AddColumns(c2)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Atlas) atDefault(c1 *Column, c2 *schema.Column) error {
|
||||
if c1.Default == nil || !a.sqlDialect.supportsDefault(c1) {
|
||||
return nil
|
||||
|
||||
@@ -38,6 +38,7 @@ type Table struct {
|
||||
ForeignKeys []*ForeignKey
|
||||
Annotation *entsql.Annotation
|
||||
Comment string
|
||||
View bool // Indicate the table is a view.
|
||||
}
|
||||
|
||||
// NewTable returns a new table with the given name.
|
||||
@@ -48,6 +49,13 @@ func NewTable(name string) *Table {
|
||||
}
|
||||
}
|
||||
|
||||
// NewView returns a new view with the given name.
|
||||
func NewView(name string) *Table {
|
||||
t := NewTable(name)
|
||||
t.View = true
|
||||
return t
|
||||
}
|
||||
|
||||
// SetComment sets the table comment.
|
||||
func (t *Table) SetComment(c string) *Table {
|
||||
t.Comment = c
|
||||
|
||||
Reference in New Issue
Block a user