Files
ent/entc/gen/template/builder/update.tmpl
2020-08-01 18:43:39 +03:00

260 lines
7.8 KiB
Cheetah

{{/*
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.
*/}}
{{ define "update" }}
{{ $pkg := base $.Config.Package }}
{{ template "header" $ }}
{{ template "import" $ }}
import (
{{- range $path := $.SiblingImports }}
"{{ $path }}"
{{- end }}
)
{{ $builder := $.UpdateName }}
{{ $receiver := receiver $builder }}
{{ $mutation := print $receiver ".mutation" }}
// {{ $builder }} is the builder for updating {{ $.Name }} entities.
type {{ $builder }} struct {
config
{{- template "update/fields" $ -}}
predicates []predicate.{{ $.Name }}
}
// Where adds a new predicate for the builder.
func ({{ $receiver}} *{{ $builder }}) Where(ps ...predicate.{{ $.Name }}) *{{ $builder }} {
{{ $receiver}}.predicates = append({{ $receiver}}.predicates, ps...)
return {{ $receiver }}
}
{{ with extend $ "Builder" $builder }}
{{ template "setter" . }}
{{ end }}
{{ with extend $ "Builder" $builder }}
{{ template "update/edges" . }}
{{ end }}
// Save executes the query and returns the number of rows/vertices matched by this operation.
func ({{ $receiver }} *{{ $builder }}) Save(ctx context.Context) (int, error) {
{{ with extend $ "Receiver" $receiver "Package" $pkg "ZeroValue" 0 -}}
{{ template "update/save" . }}
{{- end -}}
var (
err error
affected int
)
if len({{ $receiver }}.hooks) == 0 {
affected, err = {{ $receiver }}.{{ $.Storage }}Save(ctx)
} else {
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*{{ $.MutationName }})
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
{{ $mutation }} = mutation
affected, err = {{ $receiver }}.{{ $.Storage }}Save(ctx)
mutation.done = true
return affected, err
})
for i := len({{ $receiver }}.hooks) - 1; i >= 0; i-- {
mut = {{ $receiver }}.hooks[i](mut)
}
if _, err := mut.Mutate(ctx, {{ $mutation }}); err != nil {
return 0, err
}
}
return affected, err
}
// SaveX is like Save, but panics if an error occurs.
func ({{ $receiver }} *{{ $builder }}) SaveX(ctx context.Context) int {
affected, err := {{ $receiver }}.Save(ctx)
if err != nil {
panic(err)
}
return affected
}
// Exec executes the query.
func ({{ $receiver }} *{{ $builder }}) Exec(ctx context.Context) error {
_, err := {{ $receiver }}.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func ({{ $receiver }} *{{ $builder }}) ExecX(ctx context.Context) {
if err := {{ $receiver }}.Exec(ctx); err != nil {
panic(err)
}
}
{{ with extend $ "Builder" $builder "Package" $pkg }}
{{ $tmpl := printf "dialect/%s/update" $.Storage }}
{{ xtemplate $tmpl . }}
{{ end }}
{{ $onebuilder := $.UpdateOneName }}
{{ $receiver = receiver $onebuilder }}
{{ $mutation = print $receiver ".mutation" }}
// {{ $onebuilder }} is the builder for updating a single {{ $.Name }} entity.
type {{ $onebuilder }} struct {
config
{{- template "update/fields" $ }}
}
{{ with extend $ "Builder" $onebuilder }}
{{ template "setter" . }}
{{ end }}
{{ with extend $ "Builder" $onebuilder }}
{{ template "update/edges" . }}
{{ end }}
// Save executes the query and returns the updated entity.
func ({{ $receiver }} *{{ $onebuilder }} ) Save(ctx context.Context) (*{{ $.Name }}, error) {
{{ with extend $ "Receiver" $receiver "Package" $pkg "ZeroValue" "nil" -}}
{{ template "update/save" . }}
{{- end -}}
var (
err error
node *{{ $.Name }}
)
if len({{ $receiver }}.hooks) == 0 {
node, err = {{ $receiver }}.{{ $.Storage }}Save(ctx)
} else {
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*{{ $.MutationName }})
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
{{ $mutation }} = mutation
node, err = {{ $receiver }}.{{ $.Storage }}Save(ctx)
mutation.done = true
return node, err
})
for i := len({{ $receiver }}.hooks) - 1; i >= 0; i-- {
mut = {{ $receiver }}.hooks[i](mut)
}
if _, err := mut.Mutate(ctx, {{ $mutation }}); err != nil {
return nil, err
}
}
return node, err
}
// SaveX is like Save, but panics if an error occurs.
func ({{ $receiver }} *{{ $onebuilder }}) SaveX(ctx context.Context) *{{ $.Name }} {
{{ $.Receiver }}, err := {{ $receiver }}.Save(ctx)
if err != nil {
panic(err)
}
return {{ $.Receiver }}
}
// Exec executes the query on the entity.
func ({{ $receiver }} *{{ $onebuilder }}) Exec(ctx context.Context) error {
_, err := {{ $receiver }}.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func ({{ $receiver }} *{{ $onebuilder }}) ExecX(ctx context.Context) {
if err := {{ $receiver }}.Exec(ctx); err != nil {
panic(err)
}
}
{{ with extend $ "Builder" $onebuilder "Package" $pkg }}
{{ $tmpl := printf "dialect/%s/update" $.Storage }}
{{ xtemplate $tmpl . }}
{{ end }}
{{ end }}
{{/* shared struct fields between the two updaters */}}
{{ define "update/fields"}}
hooks []Hook
mutation *{{ $.MutationName }}
{{ end }}
{{/* shared edges removal between the two updaters */}}
{{ define "update/edges" }}
{{ $builder := pascal .Scope.Builder }}
{{ $receiver := receiver $builder }}
{{ $mutation := print $receiver ".mutation" }}
{{ range $_, $e := $.Edges }}
{{ if $e.Unique }}
{{ $func := print "Clear" $e.StructField }}
// {{ $func }} clears the {{ $e.Name }} edge to {{ $e.Type.Name }}.
func ({{ $receiver }} *{{ $builder }}) {{ $func }}() *{{ $builder }} {
{{ $mutation }}.{{ $func }}()
return {{ $receiver }}
}
{{ else }}
{{ $p := lower (printf "%.1s" $e.Type.Name) }}
{{/* if the name of the parameter conflicts with the receiver name */}}
{{ 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 ...{{ $e.Type.ID.Type }}) *{{ $builder }} {
{{ $mutation }}.{{ $idsFunc }}(ids...)
return {{ $receiver }}
}
{{ $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([]{{ $e.Type.ID.Type }}, len({{ $p }}))
{{ $i := "i" }}{{ if eq $i $p }}{{ $i = "j" }}{{ end -}}
for {{ $i }} := range {{ $p }} {
ids[{{ $i }}] = {{ $p }}[{{ $i }}].ID
}
return {{ $receiver }}.{{ $idsFunc }}(ids...)
}
{{ end }}
{{ end }}
{{ end }}
{{/* shared template for the save method of the 2 builders */}}
{{ define "update/save" }}
{{- $pkg := .Scope.Package -}}
{{- $zero := .Scope.ZeroValue }}
{{- $receiver := .Scope.Receiver -}}
{{- $mutation := print $receiver ".mutation" -}}
{{- range $_, $f := $.Fields -}}
{{- if $f.UpdateDefault -}}
if _, ok := {{ $mutation }}.{{ $f.MutationGet }}(); !ok {{ if $f.Optional }} && !{{ $mutation }}.{{ $f.StructField }}Cleared() {{ end }} {
v := {{ $.Package }}.{{ $f.UpdateDefaultName }}{{ if $f.IsTime }}(){{ end }}
{{ $mutation }}.Set{{ $f.StructField }}(v)
}
{{ end -}}
{{ with and (or $f.Validators $f.IsEnum) (not $f.Immutable) -}}
if v, ok := {{ $mutation }}.{{ $f.MutationGet }}(); ok {
{{- $basic := $f.BasicType "v" }}
if err := {{ $.Package }}.{{ $f.Validator }}({{ $basic }}); err != nil {
return {{ $zero }}, &ValidationError{Name: "{{ $f.Name }}", err: fmt.Errorf("{{ $pkg }}: validator failed for field \"{{ $f.Name }}\": %w", err)}
}
}
{{ end -}}
{{ end -}}
{{- range $_, $e := $.Edges }}
{{ if and $e.Unique (not $e.Optional) -}}
if _, ok := {{ $mutation }}.{{ $e.StructField }}ID(); {{ $mutation }}.{{ $e.StructField }}Cleared() && !ok {
return {{ $zero }}, errors.New("{{ $pkg }}: clearing a unique edge \"{{ $e.Name }}\"")
}
{{ end -}}
{{ end -}}
{{ end }}