mirror of
https://github.com/ent/ent.git
synced 2026-05-24 09:31:56 +03:00
301 lines
8.8 KiB
Cheetah
301 lines
8.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) {
|
|
var (
|
|
err error
|
|
affected int
|
|
)
|
|
{{- if $.HasUpdateDefault }}
|
|
{{ $receiver }}.defaults()
|
|
{{- end }}
|
|
if len({{ $receiver }}.hooks) == 0 {
|
|
{{- if $.HasUpdateCheckers }}
|
|
if err = {{ $receiver }}.check(); err != nil {
|
|
return 0, err
|
|
}
|
|
{{- end }}
|
|
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)
|
|
}
|
|
{{- if $.HasUpdateCheckers }}
|
|
if err = {{ $receiver }}.check(); err != nil {
|
|
return 0, err
|
|
}
|
|
{{- end }}
|
|
{{ $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 $ "Receiver" $receiver "Package" $pkg "Builder" $builder }}
|
|
{{ template "update/checks" . }}
|
|
{{ end }}
|
|
|
|
{{ 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) {
|
|
var (
|
|
err error
|
|
node *{{ $.Name }}
|
|
)
|
|
{{- if $.HasUpdateDefault }}
|
|
{{ $receiver }}.defaults()
|
|
{{- end }}
|
|
if len({{ $receiver }}.hooks) == 0 {
|
|
{{- if $.HasUpdateCheckers }}
|
|
if err = {{ $receiver }}.check(); err != nil {
|
|
return nil, err
|
|
}
|
|
{{- end }}
|
|
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)
|
|
}
|
|
{{- if $.HasUpdateCheckers }}
|
|
if err = {{ $receiver }}.check(); err != nil {
|
|
return nil, err
|
|
}
|
|
{{- end }}
|
|
{{ $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 }} {
|
|
node, err := {{ $receiver }}.Save(ctx)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return node
|
|
}
|
|
|
|
// 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 $ "Receiver" $receiver "Package" $pkg "Builder" $onebuilder }}
|
|
{{ template "update/checks" . }}
|
|
{{ end }}
|
|
|
|
{{ 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 }}
|
|
{{ $func := $e.MutationClear }}
|
|
// {{ $func }} clears {{ if $e.Unique }}the "{{ $e.Name }}" edge{{ else }}all "{{ $e.Name }}" edges{{ end }} to type {{ $e.Type.Name }}.
|
|
func ({{ $receiver }} *{{ $builder }}) {{ $func }}() *{{ $builder }} {
|
|
{{ $mutation }}.{{ $func }}()
|
|
return {{ $receiver }}
|
|
}
|
|
{{ if not $e.Unique }}
|
|
{{ $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 2 update builders */}}
|
|
{{ define "update/checks" }}
|
|
{{ $pkg := .Scope.Package }}
|
|
{{ $receiver := .Scope.Receiver }}
|
|
{{ $builder := pascal .Scope.Builder }}
|
|
{{ $mutation := print $receiver ".mutation" }}
|
|
|
|
{{ if $.HasUpdateDefault }}
|
|
// defaults sets the default values of the builder before save.
|
|
func ({{ $receiver }} *{{ $builder }}) defaults() {
|
|
{{- 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 }}
|
|
{{- end }}
|
|
}
|
|
{{ end }}
|
|
|
|
{{ if $.HasUpdateCheckers }}
|
|
// check runs all checks and user-defined validators on the builder.
|
|
func ({{ $receiver }} *{{ $builder }}) check() error {
|
|
{{- range $f := $.Fields }}
|
|
{{- 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 &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 errors.New("{{ $pkg }}: clearing a required unique edge \"{{ $e.Name }}\"")
|
|
}
|
|
{{- end }}
|
|
{{- end }}
|
|
return nil
|
|
}
|
|
{{ end }}
|
|
|
|
{{ end }} |