entc/gen: add edge-field api for schema and codegen (#1213)

This commit is contained in:
Ariel Mashraki
2021-03-07 22:51:17 +02:00
committed by GitHub
parent eeb5bc7141
commit c0fd7c1305
203 changed files with 13038 additions and 2736 deletions

View File

@@ -55,7 +55,7 @@ func ({{ $receiver }} *{{ $builder }}) createSpec() (*{{ $.Name }}, *sqlgraph.Cr
_spec.ID.Value = id
}
{{- end }}
{{- range $f := $.Fields }}
{{- range $f := $.MutationFields }}
if value, ok := {{ $mutation }}.{{ $f.MutationGet }}(); ok {
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
Type: field.{{ $f.Type.ConstName }},
@@ -70,6 +70,10 @@ func ({{ $receiver }} *{{ $builder }}) createSpec() (*{{ $.Name }}, *sqlgraph.Cr
{{- with extend $ "Edge" $e "Nodes" true "Zero" "nil" }}
{{ template "dialect/sql/defedge" . }}{{/* defined in sql/update.tmpl */}}
{{- end }}
{{- if $e.OwnFK }}
{{- $fk := $e.ForeignKey }}
_node.{{ $fk.StructField }} = {{ if $fk.Field.Nillable }}&{{ end }}nodes[0]
{{- end }}
_spec.Edges = append(_spec.Edges, edge)
}
{{- end }}

View File

@@ -27,7 +27,7 @@ func (*{{ $.Name }}) scanValues(columns []string) ([]interface{}, error) {
case {{ range $i, $c := $columns }}{{ if ne $i 0 }},{{ end }}{{ $.Package }}.{{ $c }}{{ end }}:
values[i] = &{{ $type }}{}
{{- end }}
{{- range $i, $fk := $.ForeignKeys }}
{{- range $i, $fk := $.UnexportedForeignKeys }}
{{- $f := $fk.Field }}
case {{ $.Package }}.ForeignKeys[{{ $i }}]: // {{ $f.Name }}
values[i] = &{{ if not $f.UserDefined }}sql.NullInt64{{ else }}{{ $f.NullType }}{{ end }}{}
@@ -66,19 +66,19 @@ func ({{ $receiver }} *{{ $.Name }}) assignValues(columns []string, values []int
{{ template "dialect/sql/decode/field" . }}
{{- end }}
{{- end }}
{{- range $i, $fk := $.ForeignKeys }}
{{- range $i, $fk := $.UnexportedForeignKeys }}
{{- $f := $fk.Field }}
case {{ $.Package }}.ForeignKeys[{{ $i }}]:
{{- if and $f.UserDefined (or $f.IsString $f.IsUUID) }}
{{- with extend $ "Idx" $idx "Field" $f "Rec" $receiver "StructField" $f.Name }}
case {{ if $fk.UserDefined }}{{ $.Package }}.{{ $.ID.Constant }}{{ else }}{{ $.Package }}.ForeignKeys[{{ $i }}]{{ end }}:
{{- if or $fk.UserDefined (and $f.UserDefined (or $f.IsString $f.IsUUID)) }}
{{- with extend $ "Idx" $idx "Field" $f "Rec" $receiver "StructField" $fk.StructField }}
{{ template "dialect/sql/decode/field" . }}
{{- end }}
{{- else }}
if value, ok := values[{{ $idx }}].(*sql.NullInt64); !ok {
return fmt.Errorf("unexpected type %T for edge-field {{ $f.Name}}", value)
} else if value.Valid {
{{ $receiver }}.{{ $f.Name }} = new({{ $f.Type }})
*{{ $receiver }}.{{ $f.Name }} = {{ $f.Type }}(value.Int64)
{{ $receiver }}.{{ $fk.StructField }} = new({{ $f.Type }})
{{ if $f.Nillable }}*{{ end }}{{ $receiver }}.{{ $fk.StructField }} = {{ $f.Type }}(value.Int64)
}
{{- end }}
{{- end }}
@@ -123,11 +123,3 @@ func ({{ $receiver }} *{{ $.Name }}) assignValues(columns []string, values []int
{{ define "dialect/sql/decode/many" }}
{{ end }}
{{/* Additional fields for the generated model for holding the foreign-keys */}}
{{ define "dialect/sql/model/fields" }}
{{- range $fk := $.ForeignKeys }}
{{- $f := $fk.Field }}
{{ $f.Name }} {{ if $f.Nillable }}*{{ end }}{{ $f.Type }}
{{- end }}
{{ end }}

View File

@@ -0,0 +1,19 @@
{{/*
Copyright 2019-present Facebook Inc. All rights reserved.
This source code is licensed under the Apache 2.0 license found
in the LICENSE file in the root directory of this source tree.
*/}}
{{/* Additional fields for the generated model for holding the foreign-keys */}}
{{ define "dialect/sql/model/fields" }}
{{- range $fk := $.UnexportedForeignKeys }}
{{- $f := $fk.Field }}
{{ $fk.StructField }} {{ if $f.Nillable }}*{{ end }}{{ $f.Type }}
{{- end }}
{{- /* Allow adding struct fields by ent extensions or user templates.*/}}
{{- with $tmpls := matchTemplate "dialect/sql/model/fields/*" }}
{{- range $tmpl := $tmpls }}
{{- xtemplate $tmpl $ }}
{{- end }}
{{- end }}
{{ end }}

View File

@@ -30,7 +30,7 @@ in the LICENSE file in the root directory of this source tree.
{{- end }}
{{ end }}
{{/* variables needed for sql dialects. */}}
{{/* Variables needed for sql dialects. */}}
{{ define "dialect/sql/meta/variables" }}
// Columns holds all SQL columns for {{ lower $.Name }} fields.
var Columns = []string{
@@ -39,9 +39,10 @@ in the LICENSE file in the root directory of this source tree.
{{ $f.Constant }},
{{- end }}
}
{{/* if any of the edges owns a foreign-key */}}
{{ with $.ForeignKeys }}
// ForeignKeys holds the SQL foreign-keys that are owned by the {{ $.Name }} type.
{{/* If any of the edges owns a foreign-key */}}
{{ with $.UnexportedForeignKeys }}
// ForeignKeys holds the SQL foreign-keys that are owned by the "{{ $.Table }}"
// table and are not defined as standalone fields in the schema.
var ForeignKeys = []string{
{{- range $fk := . }}
"{{ $fk.Edge.Rel.Column }}",
@@ -71,7 +72,7 @@ func ValidColumn(column string) bool {
return true
}
}
{{- with $.ForeignKeys }}
{{- with $.UnexportedForeignKeys }}
for i := range ForeignKeys {
if column == ForeignKeys[i] {
return true

View File

@@ -6,7 +6,7 @@ in the LICENSE file in the root directory of this source tree.
{{/* Additional fields for the builder. */}}
{{ define "dialect/sql/query/fields" }}
{{- with $.ForeignKeys }}
{{- with $.UnexportedForeignKeys }}
withFKs bool
{{- end }}
{{- end }}
@@ -19,7 +19,7 @@ in the LICENSE file in the root directory of this source tree.
func ({{ $receiver }} *{{ $builder }}) sqlAll(ctx context.Context) ([]*{{ $.Name }}, error) {
var (
nodes = []*{{ $.Name }}{}
{{- with $.ForeignKeys }}
{{- with $.UnexportedForeignKeys }}
withFKs = {{ $receiver }}.withFKs
{{- end }}
_spec = {{ $receiver }}.querySpec()
@@ -31,7 +31,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlAll(ctx context.Context) ([]*{{ $.Name
}
{{- end }}
)
{{- with $.ForeignKeys }}
{{- with $.UnexportedForeignKeys }}
{{- with $.FKEdges }}
if {{ range $i, $e := . }}{{ if gt $i 0 }} || {{ end }}{{ $receiver }}.{{ $e.EagerLoadField }} != nil{{ end }} {
withFKs = true
@@ -136,6 +136,14 @@ func ({{ $receiver }} *{{ $builder }}) querySpec() *sqlgraph.QuerySpec {
{{ template "dialect/sql/query/selector" $ }}
{{- /* Allow adding methods to the query-builder by ent extensions or user templates.*/}}
{{- with $tmpls := matchTemplate "dialect/sql/query/additional/*" }}
{{- range $tmpl := $tmpls }}
{{- xtemplate $tmpl $ }}
{{- end }}
{{- end }}
{{ end }}
{{ define "dialect/sql/query/selector" }}
@@ -308,9 +316,9 @@ func ({{ $receiver }} *{{ $builder }}) sqlQuery(ctx context.Context) *sql.Select
ids := make([]{{ $e.Type.ID.Type }}, 0, len(nodes))
nodeids := make(map[{{ $e.Type.ID.Type }}][]*{{ $.Name }})
for i := range nodes {
{{- $fk := $e.FKField }}
fk := nodes[i].{{ $e.StructFKField }}
{{- if $fk.Nillable }}
{{- $fk := $e.ForeignKey }}
fk := nodes[i].{{ $fk.StructField }}
{{- if $fk.Field.Nillable }}
if fk != nil {
ids = append(ids, *fk)
nodeids[*fk] = append(nodeids[*fk], nodes[i])
@@ -328,7 +336,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlQuery(ctx context.Context) *sql.Select
for _, n := range neighbors {
nodes, ok := nodeids[n.ID]
if !ok {
return nil, fmt.Errorf(`unexpected foreign-key "{{ $fk.Name }}" returned %v`, n.ID)
return nil, fmt.Errorf(`unexpected foreign-key "{{ $fk.Field.Name }}" returned %v`, n.ID)
}
for i := range nodes {
nodes[i].Edges.{{ $e.StructField }} = n
@@ -344,7 +352,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlQuery(ctx context.Context) *sql.Select
nodes[i].Edges.{{ $e.StructField }} = []*{{ $e.Type.Name }}{}
{{- end }}
}
{{- with $e.Type.ForeignKeys }}
{{- with $e.Type.UnexportedForeignKeys }}
query.withFKs = true
{{- end }}
query.Where(predicate.{{ $e.Type.Name }}(func(s *sql.Selector) {
@@ -355,16 +363,16 @@ func ({{ $receiver }} *{{ $builder }}) sqlQuery(ctx context.Context) *sql.Select
return nil, err
}
for _, n := range neighbors {
fk := n.{{ $e.StructFKField }}
{{- $fk := $e.FKField }}
{{- if $fk.Nillable }}
{{- $fk := $e.ForeignKey }}
fk := n.{{ $fk.StructField }}
{{- if $fk.Field.Nillable }}
if fk == nil {
return nil, fmt.Errorf(`foreign-key "{{ $fk.Name }}" is nil for node %v`, n.ID)
return nil, fmt.Errorf(`foreign-key "{{ $fk.Field.Name }}" is nil for node %v`, n.ID)
}
{{- end }}
node, ok := nodeids[{{ if $fk.Nillable }}*{{ end }}fk]
node, ok := nodeids[{{ if $fk.Field.Nillable }}*{{ end }}fk]
if !ok {
return nil, fmt.Errorf(`unexpected foreign-key "{{ $fk.Name }}" returned %v for node %v`, {{ if $fk.Nillable }}*{{ end }}fk, n.ID)
return nil, fmt.Errorf(`unexpected foreign-key "{{ $fk.Field.Name }}" returned %v for node %v`, {{ if $fk.Field.Nillable }}*{{ end }}fk, n.ID)
}
node.Edges.{{ $e.StructField }} = {{ if $e.Unique }}n{{ else }}append(node.Edges.{{ $e.StructField }}, n){{ end }}
}

View File

@@ -38,7 +38,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
}
}
}
{{- range $f := $.Fields }}
{{- range $f := $.MutationFields }}
{{- if or (not $f.Immutable) $f.UpdateDefault }}
if value, ok := {{ $mutation }}.{{ $f.MutationGet }}(); ok {
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
@@ -66,7 +66,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
}
{{- end }}
{{- end }}
{{- range $_, $e := $.Edges }}
{{- range $e := $.Edges }}
if {{ $mutation }}.{{ $e.MutationCleared }}() {
{{- with extend $ "Edge" $e }}
{{ template "dialect/sql/defedge" . }}