Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions doc/md/schema-fields.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,22 @@ func (User) Fields() []ent.Field {
}
```

## Deprecated Fields

The `Deprecated` method can be used to mark a field as deprecated. Deprecated fields are not
selected by default in queries, and their struct fields are annotated as `Deprecated` in the
generated code.

```go
// Fields of the user.
func (User) Fields() []ent.Field {
return []ent.Field{
field.String("name").
Deprecated("use `full_name` instead"),
}
}
```

## Storage Key

Custom storage name can be configured using the `StorageKey` method.
Expand Down
11 changes: 10 additions & 1 deletion entc/gen/template/dialect/sql/meta.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ in the LICENSE file in the root directory of this source tree.
{{ $.ID.Constant }},
{{- end }}
{{- range $f := $.Fields }}
{{ $f.Constant }},
{{- if not $f.IsDeprecated }}
{{ $f.Constant }},
{{- end }}
{{- end }}
}
{{/* If any of the edges owns a foreign-key */}}
Expand Down Expand Up @@ -92,6 +94,13 @@ func ValidColumn(column string) bool {
}
}
{{- end }}
{{- with $.DeprecatedFields }}
for _, f := range [...]string{ {{- range . }}{{ .Constant }},{{ end }} } {
if column == f {
return true
}
}
{{- end }}
return false
}
{{ end }}
Expand Down
4 changes: 4 additions & 0 deletions entc/gen/template/ent.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,10 @@ type {{ $slice }} []*{{ $.Name }}
{{- else }}
// {{ $.StructField }} holds the value of the "{{ $.Name }}" field.
{{- end }}
{{- if $.IsDeprecated }}
//
// Deprecated: {{ with $.DeprecationReason }}{{ . }}{{ else }}Field "{{ $.Name }}" was marked as deprecated in the schema.{{ end }}
{{- end }}
{{- end }}

{{/* A template for setting the edge comment. */}}
Expand Down
22 changes: 22 additions & 0 deletions entc/gen/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,17 @@ func (f Field) IsEnum() bool { return f.Type != nil && f.Type.Type == field.Type
// that was referenced by one of the edges.
func (f Field) IsEdgeField() bool { return f.fk != nil }

// IsDeprecated returns true if the field is deprecated.
func (f Field) IsDeprecated() bool { return f.def != nil && f.def.Deprecated }

// DeprecationReason returns the deprecation reason of the field.
func (f Field) DeprecationReason() string {
if f.def != nil {
return f.def.DeprecatedReason
}
return ""
}

// Edge returns the edge this field is point to.
func (f Field) Edge() (*Edge, error) {
if !f.IsEdgeField() {
Expand Down Expand Up @@ -1425,6 +1436,17 @@ func (t Type) HasValueScanner() bool {
return false
}

// DeprecatedFields returns all deprecated fields of the type.
func (t Type) DeprecatedFields() []*Field {
fs := make([]*Field, 0, len(t.Fields))
for _, f := range t.Fields {
if f.IsDeprecated() {
fs = append(fs, f)
}
}
return fs
}

// HasValueScanner indicates if the field has (an external) ValueScanner.
func (f Field) HasValueScanner() bool {
return f.def != nil && f.def.ValueScanner
Expand Down
3 changes: 2 additions & 1 deletion entc/integration/ent/schema/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ func (Task) Fields() []ent.Field {
Immutable().
Nillable(),
field.String("name").
Optional(),
Optional().
Deprecated(),
field.String("owner").
Optional(),
field.Int("order").
Expand Down
2 changes: 2 additions & 0 deletions entc/integration/ent/task.go

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

6 changes: 5 additions & 1 deletion entc/integration/ent/task/task.go

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

2 changes: 2 additions & 0 deletions entc/integration/gremlin/ent/task.go

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

6 changes: 4 additions & 2 deletions entc/integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -874,12 +874,14 @@ func ExecQuery(t *testing.T, client *ent.Client) {
func NillableRequired(t *testing.T, client *ent.Client) {
require := require.New(t)
ctx := context.Background()
client.Task.Create().ExecX(ctx)
client.Task.Create().SetName("Name").ExecX(ctx)
tk := client.Task.Query().OnlyX(ctx)
require.Empty(tk.Name, "Name is not selected by default")
require.NotNil(tk.CreatedAt, "field value should be populated by default by the database")
require.False(reflect.ValueOf(tk.Update()).MethodByName("SetNillableCreatedAt").IsValid(), "immutable-nillable should not have SetNillable setter on update")
tk = client.Task.Query().Select(enttask.FieldID, enttask.FieldPriority).OnlyX(ctx)
tk = client.Task.Query().Select(enttask.FieldID, enttask.FieldPriority, enttask.FieldName).OnlyX(ctx)
require.Nil(tk.CreatedAt, "field should not be populated when it is not selected")
require.Equal("Name", tk.Name, "Name should be populated when selected manually")
}

func Predicate(t *testing.T, client *ent.Client) {
Expand Down
6 changes: 3 additions & 3 deletions entc/internal/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func merge(local, other *gen.Snapshot) {
switch match, ok := locals[schema.Name]; {
case !ok:
local.Schemas = append(local.Schemas, schema)
case ok:
default:
mergeSchema(match, schema)
}
}
Expand Down Expand Up @@ -167,7 +167,7 @@ func mergeSchema(local, other *load.Schema) {
switch match, ok := fields[f.Name]; {
case !ok:
local.Fields = append(local.Fields, f)
case ok:
default:
mergeField(match, f)
}
}
Expand All @@ -179,7 +179,7 @@ func mergeSchema(local, other *load.Schema) {
switch match, ok := edges[e.Name]; {
case !ok:
local.Edges = append(local.Edges, e)
case ok:
default:
mergeEdge(match, e)
}
}
Expand Down
80 changes: 42 additions & 38 deletions entc/load/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,27 +38,29 @@ type Position struct {

// Field represents an ent.Field that was loaded from a complied user package.
type Field struct {
Name string `json:"name,omitempty"`
Info *field.TypeInfo `json:"type,omitempty"`
ValueScanner bool `json:"value_scanner,omitempty"`
Tag string `json:"tag,omitempty"`
Size *int64 `json:"size,omitempty"`
Enums []struct{ N, V string } `json:"enums,omitempty"`
Unique bool `json:"unique,omitempty"`
Nillable bool `json:"nillable,omitempty"`
Optional bool `json:"optional,omitempty"`
Default bool `json:"default,omitempty"`
DefaultValue any `json:"default_value,omitempty"`
DefaultKind reflect.Kind `json:"default_kind,omitempty"`
UpdateDefault bool `json:"update_default,omitempty"`
Immutable bool `json:"immutable,omitempty"`
Validators int `json:"validators,omitempty"`
StorageKey string `json:"storage_key,omitempty"`
Position *Position `json:"position,omitempty"`
Sensitive bool `json:"sensitive,omitempty"`
SchemaType map[string]string `json:"schema_type,omitempty"`
Annotations map[string]any `json:"annotations,omitempty"`
Comment string `json:"comment,omitempty"`
Name string `json:"name,omitempty"`
Info *field.TypeInfo `json:"type,omitempty"`
ValueScanner bool `json:"value_scanner,omitempty"`
Tag string `json:"tag,omitempty"`
Size *int64 `json:"size,omitempty"`
Enums []struct{ N, V string } `json:"enums,omitempty"`
Unique bool `json:"unique,omitempty"`
Nillable bool `json:"nillable,omitempty"`
Optional bool `json:"optional,omitempty"`
Default bool `json:"default,omitempty"`
DefaultValue any `json:"default_value,omitempty"`
DefaultKind reflect.Kind `json:"default_kind,omitempty"`
UpdateDefault bool `json:"update_default,omitempty"`
Immutable bool `json:"immutable,omitempty"`
Validators int `json:"validators,omitempty"`
StorageKey string `json:"storage_key,omitempty"`
Position *Position `json:"position,omitempty"`
Sensitive bool `json:"sensitive,omitempty"`
SchemaType map[string]string `json:"schema_type,omitempty"`
Annotations map[string]any `json:"annotations,omitempty"`
Comment string `json:"comment,omitempty"`
Deprecated bool `json:"deprecated,omitempty"`
DeprecatedReason string `json:"deprecated_reason,omitempty"`
}

// Edge represents an ent.Edge that was loaded from a complied user package.
Expand Down Expand Up @@ -121,23 +123,25 @@ func NewField(fd *field.Descriptor) (*Field, error) {
return nil, fmt.Errorf("field %q: %v", fd.Name, fd.Err)
}
sf := &Field{
Name: fd.Name,
Info: fd.Info,
ValueScanner: fd.ValueScanner != nil,
Tag: fd.Tag,
Enums: fd.Enums,
Unique: fd.Unique,
Nillable: fd.Nillable,
Optional: fd.Optional,
Default: fd.Default != nil,
UpdateDefault: fd.UpdateDefault != nil,
Immutable: fd.Immutable,
StorageKey: fd.StorageKey,
Validators: len(fd.Validators),
Sensitive: fd.Sensitive,
SchemaType: fd.SchemaType,
Annotations: make(map[string]any),
Comment: fd.Comment,
Name: fd.Name,
Info: fd.Info,
ValueScanner: fd.ValueScanner != nil,
Tag: fd.Tag,
Enums: fd.Enums,
Unique: fd.Unique,
Nillable: fd.Nillable,
Optional: fd.Optional,
Default: fd.Default != nil,
UpdateDefault: fd.UpdateDefault != nil,
Immutable: fd.Immutable,
StorageKey: fd.StorageKey,
Validators: len(fd.Validators),
Sensitive: fd.Sensitive,
SchemaType: fd.SchemaType,
Annotations: make(map[string]any),
Comment: fd.Comment,
Deprecated: fd.Deprecated,
DeprecatedReason: fd.DeprecatedReason,
}
for _, at := range fd.Annotations {
sf.addAnnotation(at)
Expand Down
Loading