dialect/sql/schema: allow setting table comments (#3365)

This commit is contained in:
Ariel Mashraki
2023-03-04 20:50:26 +02:00
committed by GitHub
parent f16451eab8
commit 3b7715b552
11 changed files with 55 additions and 9 deletions

View File

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

View File

@@ -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.
@@ -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
@@ -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

View File

@@ -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"
)
@@ -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"),
}
}

View File

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

View File

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

View File

@@ -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"
)
@@ -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)

View File

@@ -14,7 +14,7 @@ import (
"entgo.io/ent/entc/integration/migrate/entv2/media"
)
// Media is the model entity for the Media schema.
// Comment that appears in both the schema and the generated code
type Media struct {
config `json:"-"`
// ID of the ent.

View File

@@ -96,6 +96,7 @@ var (
// MediaTable holds the schema information for the "media" table.
MediaTable = &schema.Table{
Name: "media",
Comment: "Comment that appears in both the schema and the generated code",
Columns: MediaColumns,
PrimaryKey: []*schema.Column{MediaColumns[0]},
Indexes: []*schema.Index{

View File

@@ -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{

View File

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

View File

@@ -30,7 +30,7 @@ type CommentAnnotation struct {
}
// Name implements the Annotation interface.
func (c *CommentAnnotation) Name() string {
func (*CommentAnnotation) Name() string {
return "Comment"
}