mirror of
https://github.com/ent/ent.git
synced 2026-05-24 09:31:56 +03:00
entc/gen: initial support for user-defined ids
Summary: Pull Request resolved: https://github.com/facebookincubator/ent/pull/162 Reviewed By: alexsn Differential Revision: D18485086 fbshipit-source-id: 9bb6ccff592bc0cb8b218625161ed492f67bc170
This commit is contained in:
committed by
Facebook Github Bot
parent
e161ecc29c
commit
d9da7243f9
@@ -26,7 +26,8 @@ var (
|
||||
Funcs = template.FuncMap{
|
||||
"ops": ops,
|
||||
"add": add,
|
||||
"append": reflect.AppendSlice,
|
||||
"append": reflect.Append,
|
||||
"appends": reflect.AppendSlice,
|
||||
"order": order,
|
||||
"snake": snake,
|
||||
"pascal": pascal,
|
||||
|
||||
@@ -331,8 +331,9 @@ func (g *Graph) Tables() (all []*schema.Table) {
|
||||
})
|
||||
case M2M:
|
||||
t1, t2 := tables[n.Table()], tables[e.Type.Table()]
|
||||
c1 := &schema.Column{Name: e.Rel.Columns[0], Type: field.TypeInt}
|
||||
c2 := &schema.Column{Name: e.Rel.Columns[1], Type: field.TypeInt}
|
||||
fk1, fk2 := n.ID, e.Type.ID
|
||||
c1 := &schema.Column{Name: e.Rel.Columns[0], Type: fk1.Type.Type}
|
||||
c2 := &schema.Column{Name: e.Rel.Columns[1], Type: fk2.Type.Type}
|
||||
all = append(all, &schema.Table{
|
||||
Name: e.Rel.Table,
|
||||
Columns: []*schema.Column{c1, c2},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -17,11 +17,14 @@ in the LICENSE file in the root directory of this source tree.
|
||||
// {{ $builder }} is the builder for creating a {{ $.Name }} entity.
|
||||
type {{ $builder }} struct {
|
||||
config
|
||||
{{- if $.ID.UserDefined }}
|
||||
{{ $.ID.BuilderField }} *{{ $.ID.Type }}
|
||||
{{- end }}
|
||||
{{ range $_, $f := $.Fields }}
|
||||
{{- $f.BuilderField }} *{{ $f.Type }}
|
||||
{{ end }}
|
||||
{{- range $_, $e := $.Edges }}
|
||||
{{- $e.BuilderField }} map[{{ $.ID.Type }}]struct{}
|
||||
{{- $e.BuilderField }} map[{{ $e.Type.ID.Type }}]struct{}
|
||||
{{ end -}}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ in the LICENSE file in the root directory of this source tree.
|
||||
{{- if or (hasSuffix $builder "Update") (hasSuffix $builder "UpdateOne") }}
|
||||
{{ $updater = true }}
|
||||
{{ $fields = $.MutableFields }}
|
||||
{{- else if $.ID.UserDefined }}
|
||||
{{ $fields = append $fields $.ID }}
|
||||
{{- end }}
|
||||
|
||||
{{ range $_, $f := $fields }}
|
||||
@@ -67,9 +69,9 @@ in the LICENSE file in the root directory of this source tree.
|
||||
{{ $op := "add" }}{{ if $e.Unique }}{{ $op = "set" }}{{ end }}
|
||||
{{ $idsFunc := print (pascal $op) (singular $e.Name | pascal) "IDs" }}{{ if $e.Unique }}{{ $idsFunc = print (pascal $op) (pascal $e.Name) "ID" }}{{ end }}
|
||||
// {{ $idsFunc }} {{ $op }}s the {{ $e.Name }} edge to {{ $e.Type.Name }} by id{{ if not $e.Unique }}s{{ end }}.
|
||||
func ({{ $receiver }} *{{ $builder }}) {{ $idsFunc }}({{ if $e.Unique }}id{{ else }}ids ...{{ end }} {{ $.ID.Type }}) *{{ $builder }} {
|
||||
func ({{ $receiver }} *{{ $builder }}) {{ $idsFunc }}({{ if $e.Unique }}id{{ else }}ids ...{{ end }} {{ $e.Type.ID.Type }}) *{{ $builder }} {
|
||||
if {{ $receiver }}.{{ $e.BuilderField }} == nil {
|
||||
{{ $receiver }}.{{ $e.BuilderField }} = make(map[{{ $.ID.Type }}]struct{})
|
||||
{{ $receiver }}.{{ $e.BuilderField }} = make(map[{{ $e.Type.ID.Type }}]struct{})
|
||||
}
|
||||
{{ if $e.Unique -}}
|
||||
{{ $receiver }}.{{ $e.BuilderField }}[id] = struct{}{}
|
||||
@@ -83,7 +85,7 @@ in the LICENSE file in the root directory of this source tree.
|
||||
{{ if and $e.Unique $e.Optional }}
|
||||
{{ $nillableIDsFunc := print "SetNillable" $e.StructField "ID" }}
|
||||
// {{ $nillableIDsFunc }} sets the {{ $e.Name }} edge to {{ $e.Type.Name }} by id if the given value is not nil.
|
||||
func ({{ $receiver }} *{{ $builder }}) {{ $nillableIDsFunc }}(id *{{ $.ID.Type }}) *{{ $builder }} {
|
||||
func ({{ $receiver }} *{{ $builder }}) {{ $nillableIDsFunc }}(id *{{ $e.Type.ID.Type }}) *{{ $builder }} {
|
||||
if id != nil {
|
||||
{{ $receiver}} = {{ $receiver }}.{{ $idsFunc }}(*id)
|
||||
}
|
||||
@@ -98,7 +100,7 @@ in the LICENSE file in the root directory of this source tree.
|
||||
{{ if $e.Unique -}}
|
||||
return {{ $receiver }}.{{ $idsFunc }}({{ $p }}.ID)
|
||||
{{- else -}}
|
||||
ids := make([]{{ $.ID.Type }}, len({{ $p }}))
|
||||
ids := make([]{{ $e.Type.ID.Type }}, len({{ $p }}))
|
||||
{{ $i := "i" }}{{ if eq $i $p }}{{ $i = "j" }}{{ end -}}
|
||||
for {{ $i }} := range {{ $p }} {
|
||||
ids[{{ $i }}] = {{ $p }}[{{ $i }}].ID
|
||||
|
||||
@@ -166,11 +166,11 @@ func ({{ $receiver }} *{{ $onebuilder }}) ExecX(ctx context.Context) {
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
{{- range $_, $e := $.Edges }}
|
||||
{{- $e.BuilderField }} map[{{ $.ID.Type }}]struct{}
|
||||
{{- $e.BuilderField }} map[{{ $e.Type.ID.Type }}]struct{}
|
||||
{{ end }}
|
||||
{{- range $_, $e := $.Edges }}
|
||||
{{- $p := "removed" }}{{ if $e.Unique }}{{ $p = "cleared" }}{{ end }}
|
||||
{{- print $p $e.StructField }} {{ if $e.Unique }}bool{{ else }}map[{{ $.ID.Type }}]struct{}{{ end }}
|
||||
{{- print $p $e.StructField }} {{ if $e.Unique }}bool{{ else }}map[{{ $e.Type.ID.Type }}]struct{}{{ end }}
|
||||
{{ end -}}
|
||||
{{ end }}
|
||||
|
||||
@@ -193,9 +193,9 @@ func ({{ $receiver }} *{{ $onebuilder }}) ExecX(ctx context.Context) {
|
||||
{{ if eq $p $receiver }} {{ $p = "v" }} {{ end }}
|
||||
{{ $idsFunc := print "Remove" (singular $e.Name | pascal) "IDs" }}
|
||||
// {{ $idsFunc }} removes the {{ $e.Name }} edge to {{ $e.Type.Name }} by ids.
|
||||
func ({{ $receiver }} *{{ $builder }}) {{ $idsFunc }}(ids ...{{ $.ID.Type }}) *{{ $builder }} {
|
||||
func ({{ $receiver }} *{{ $builder }}) {{ $idsFunc }}(ids ...{{ $e.Type.ID.Type }}) *{{ $builder }} {
|
||||
if {{ $receiver }}.removed{{ $e.StructField }} == nil {
|
||||
{{ $receiver }}.removed{{ $e.StructField }} = make(map[{{ $.ID.Type }}]struct{})
|
||||
{{ $receiver }}.removed{{ $e.StructField }} = make(map[{{ $e.Type.ID.Type }}]struct{})
|
||||
}
|
||||
for i := range ids {
|
||||
{{ $receiver }}.removed{{ $e.StructField }}[ids[i]] = struct{}{}
|
||||
@@ -205,7 +205,7 @@ func ({{ $receiver }} *{{ $onebuilder }}) ExecX(ctx context.Context) {
|
||||
{{ $func := print "Remove" $e.StructField }}
|
||||
// {{ $func }} removes {{ $e.Name }} edges to {{ $e.Type.Name }}.
|
||||
func ({{ $receiver }} *{{ $builder }}) {{ $func }}({{ $p }} ...*{{ $e.Type.Name }}) *{{ $builder }} {
|
||||
ids := make([]{{ $.ID.Type }}, len({{ $p }}))
|
||||
ids := make([]{{ $e.Type.ID.Type }}, len({{ $p }}))
|
||||
{{ $i := "i" }}{{ if eq $i $p }}{{ $i = "j" }}{{ end -}}
|
||||
for {{ $i }} := range {{ $p }} {
|
||||
ids[{{ $i }}] = {{ $p }}[{{ $i }}].ID
|
||||
|
||||
@@ -61,7 +61,7 @@ func ID(id {{ $.ID.Type }}) predicate.{{ $.Name }} {
|
||||
{{/* storage specific predicates disabled for multi-storage codegen */}}
|
||||
{{ if not $.MultiStorage }}
|
||||
{{ $storage := index $.Storage 0 }}
|
||||
{{ $ops = append $ops (call $storage.Ops $f) }}
|
||||
{{ $ops = appends $ops (call $storage.Ops $f) }}
|
||||
{{ end }}
|
||||
{{ range $_, $op := $ops }}
|
||||
{{ $arg := "v" }}{{ if $op.Variadic }}{{ $arg = "vs" }}{{ end }}
|
||||
|
||||
@@ -65,6 +65,9 @@ type (
|
||||
Validators int
|
||||
// Position info of the field.
|
||||
Position *load.Position
|
||||
// UserDefined indicates that this field was defined by the loaded schema.
|
||||
// Unlike default id field, which is defined by the generator.
|
||||
UserDefined bool
|
||||
}
|
||||
|
||||
// Edge of a graph between two types.
|
||||
@@ -133,10 +136,10 @@ func NewType(c *Config, schema *load.Schema) (*Type, error) {
|
||||
},
|
||||
schema: schema,
|
||||
Name: schema.Name,
|
||||
Fields: make([]*Field, len(schema.Fields)),
|
||||
Fields: make([]*Field, 0, len(schema.Fields)),
|
||||
fields: make(map[string]*Field, len(schema.Fields)),
|
||||
}
|
||||
for i, f := range schema.Fields {
|
||||
for _, f := range schema.Fields {
|
||||
switch {
|
||||
case f.Info == nil || !f.Info.Valid():
|
||||
return nil, fmt.Errorf("invalid type for field %s", f.Name)
|
||||
@@ -155,7 +158,7 @@ func NewType(c *Config, schema *load.Schema) (*Type, error) {
|
||||
// enum types should be named as follows: typepkg.Field.
|
||||
f.Info.Ident = fmt.Sprintf("%s.%s", typ.Package(), pascal(f.Name))
|
||||
}
|
||||
typ.Fields[i] = &Field{
|
||||
tf := &Field{
|
||||
def: f,
|
||||
Name: f.Name,
|
||||
Type: f.Info,
|
||||
@@ -168,8 +171,15 @@ func NewType(c *Config, schema *load.Schema) (*Type, error) {
|
||||
Immutable: f.Immutable,
|
||||
StructTag: structTag(f.Name, f.Tag),
|
||||
Validators: f.Validators,
|
||||
UserDefined: true,
|
||||
}
|
||||
// user defined id field.
|
||||
if tf.Name == typ.ID.Name {
|
||||
typ.ID = tf
|
||||
} else {
|
||||
typ.Fields = append(typ.Fields, tf)
|
||||
typ.fields[f.Name] = tf
|
||||
}
|
||||
typ.fields[f.Name] = typ.Fields[i]
|
||||
}
|
||||
return typ, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user