Skip to content

Commit

Permalink
dialect/sql/schema: allow setting table comments (ent#3365)
Browse files Browse the repository at this point in the history
  • Loading branch information
a8m authored Mar 4, 2023
1 parent f16451e commit 3b7715b
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 9 deletions.
3 changes: 3 additions & 0 deletions dialect/sql/schema/atlas.go
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,9 @@ func (a *Atlas) tables(tables []*Table) ([]*schema.Table, error) {
ts := make([]*schema.Table, len(tables))
for i, et := range tables {
at := schema.NewTable(et.Name)
if et.Comment != "" {
at.SetComment(et.Comment)
}
a.sqlDialect.atTable(et, at)
if a.universalID && et.Name != TypeTable && len(et.PrimaryKey) == 1 {
r, err := a.pkRange(et)
Expand Down
9 changes: 8 additions & 1 deletion dialect/sql/schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Table struct {
PrimaryKey []*Column
ForeignKeys []*ForeignKey
Annotation *entsql.Annotation
Comment string
}

// NewTable returns a new table with the given name.
Expand All @@ -46,6 +47,12 @@ func NewTable(name string) *Table {
}
}

// SetComment sets the table comment.
func (t *Table) SetComment(c string) *Table {
t.Comment = c
return t
}

// AddPrimary adds a new primary key to the table.
func (t *Table) AddPrimary(c *Column) *Table {
c.Key = PrimaryKey
Expand Down Expand Up @@ -295,7 +302,7 @@ type Column struct {
typ string // row column type (used for Rows.Scan).
indexes Indexes // linked indexes.
foreign *ForeignKey // linked foreign-key.
Comment string // column comment.
Comment string // optional column comment.
}

// Expr represents a raw expression. It is used to distinguish between
Expand Down
12 changes: 7 additions & 5 deletions doc/md/schema-annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,16 @@ rows in the child table.

## Database Comments

By default, column comments are not stored in the database. However, this functionality can be enabled by using the
`WithComments(true)` annotation. For example:
By default, table and column comments are not stored in the database. However, this functionality can be enabled by
using the `WithComments(true)` annotation. For example:

```go title="ent/schema/user.go" {17-19,32-35}
```go title="ent/schema/user.go" {18-21,34-37}
package schema

import (
"entgo.io/ent"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/field"
)

Expand All @@ -108,9 +109,10 @@ type User struct {
// Annotations of the User.
func (User) Annotations() []schema.Annotation {
return []schema.Annotation{
// Adding this annotation on the
// type enables it for all fields.
// Adding this annotation to the schema enables
// comments for the table and all its fields.
entsql.WithComments(true),
schema.Comment("Comment that appears in both the schema and the generated code"),
}
}

Expand Down
3 changes: 2 additions & 1 deletion entc/gen/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,8 @@ func (g *Graph) edgeSchemas() error {
func (g *Graph) Tables() (all []*schema.Table, err error) {
tables := make(map[string]*schema.Table)
for _, n := range g.Nodes {
table := schema.NewTable(n.Table())
table := schema.NewTable(n.Table()).
SetComment(n.sqlComment())
if n.HasOneFieldID() {
table.AddPrimary(n.ID.PK())
}
Expand Down
3 changes: 3 additions & 0 deletions entc/gen/template/migrate/schema.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ var (
// {{ $table }} holds the schema information for the "{{ $t.Name }}" table.
{{ $table }} = &schema.Table{
Name: "{{ $t.Name }}",
{{- with $t.Comment }}
Comment: "{{ . }}",
{{- end }}
Columns: {{ $columns }},
PrimaryKey: []*schema.Column{
{{- range $pk := $t.PrimaryKey }}
Expand Down
16 changes: 16 additions & 0 deletions entc/gen/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/dialect/sql/schema"
"entgo.io/ent/entc/load"
entschema "entgo.io/ent/schema"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
)
Expand Down Expand Up @@ -1018,6 +1019,21 @@ func aliases(g *Graph) {
}
}

// sqlComment returns the SQL database comment for the node (table), if defined and enabled.
func (t Type) sqlComment() string {
if ant := t.EntSQL(); ant == nil || ant.WithComments == nil || !*ant.WithComments {
return ""
}
ant := &entschema.CommentAnnotation{}
if t.Annotations == nil || t.Annotations[ant.Name()] == nil {
return ""
}
if b, err := json.Marshal(t.Annotations[ant.Name()]); err == nil {
_ = json.Unmarshal(b, &ant)
}
return ant.Text
}

// Constant returns the constant name of the field.
func (f Field) Constant() string {
return "Field" + pascal(f.Name)
Expand Down
2 changes: 1 addition & 1 deletion entc/integration/migrate/entv2/media.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions entc/integration/migrate/entv2/migrate/schema.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions entc/integration/migrate/entv2/schema/media.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func (Media) Indexes() []ent.Index {
// Annotations of the Media.
func (Media) Annotations() []schema.Annotation {
return []schema.Annotation{
schema.Comment("Comment that appears in both the schema and the generated code"),
entsql.WithComments(true),
entsql.Check("text <> 'boring'"),
entsql.Checks(map[string]string{
Expand Down
12 changes: 12 additions & 0 deletions entc/integration/migrate/migrate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ func TestMySQL(t *testing.T) {
NicknameSearch(t, clientv2)
TimePrecision(t, drv, "SELECT datetime_precision FROM information_schema.columns WHERE table_schema = 'migrate' AND table_name = ? AND column_name = ?")
ColumnComments(t, drv, "SELECT column_name as name, column_comment as comment FROM information_schema.columns WHERE table_schema = 'migrate' AND table_name = 'media' ORDER BY ordinal_position")
TableComment(t, drv, "SELECT table_comment FROM information_schema.tables WHERE table_schema = 'migrate' AND table_name = 'media'")

require.NoError(t, err, root.Exec(ctx, "DROP DATABASE IF EXISTS versioned_migrate", []any{}, new(sql.Result)))
require.NoError(t, root.Exec(ctx, "CREATE DATABASE IF NOT EXISTS versioned_migrate", []any{}, new(sql.Result)))
Expand Down Expand Up @@ -142,6 +143,7 @@ func TestPostgres(t *testing.T) {
PKDefault(t, drv, `SELECT column_default FROM information_schema.columns WHERE table_name = 'zoos' AND column_name = $1`, "floor((random() * ((~ (1 << 31)))::double precision))")
IndexOpClass(t, drv)
ColumnComments(t, drv, `SELECT column_name as name, col_description(table_name::regclass::oid, ordinal_position) as comment FROM information_schema.columns WHERE table_name = 'media' ORDER BY ordinal_position`)
TableComment(t, drv, "SELECT obj_description('media'::regclass::oid)")
if version != "10" {
IncludeColumns(t, drv)
}
Expand Down Expand Up @@ -712,6 +714,16 @@ func JSONDefault(t *testing.T, drv *sql.Driver, query string) {
require.NotEmpty(t, s)
}

func TableComment(t *testing.T, drv *sql.Driver, query string) {
ctx := context.Background()
rows, err := drv.QueryContext(ctx, query)
require.NoError(t, err)
comment, err := sql.ScanString(rows)
require.NoError(t, err)
require.NoError(t, rows.Close())
require.Equal(t, "Comment that appears in both the schema and the generated code", comment)
}

func ColumnComments(t *testing.T, drv *sql.Driver, query string) {
ctx := context.Background()
rows, err := drv.QueryContext(ctx, query)
Expand Down
2 changes: 1 addition & 1 deletion schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type CommentAnnotation struct {
}

// Name implements the Annotation interface.
func (c *CommentAnnotation) Name() string {
func (*CommentAnnotation) Name() string {
return "Comment"
}

Expand Down

0 comments on commit 3b7715b

Please sign in to comment.