mirror of
https://github.com/ent/ent.git
synced 2026-03-05 19:35:23 +03:00
dialect/sql/schema: allow setting table comments (#3365)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -30,7 +30,7 @@ type CommentAnnotation struct {
|
||||
}
|
||||
|
||||
// Name implements the Annotation interface.
|
||||
func (c *CommentAnnotation) Name() string {
|
||||
func (*CommentAnnotation) Name() string {
|
||||
return "Comment"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user