{{/* 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 "create" }} {{ $pkg := base $.Config.Package }} {{ template "header" $ }} {{ template "import" $ }} import ( {{- range $path := $.SiblingImports }} "{{ $path }}" {{- end }} ) {{ $builder := $.CreateName }} {{ $receiver := receiver $builder }} {{ $mutation := print $receiver ".mutation" }} // {{ $builder }} is the builder for creating a {{ $.Name }} entity. type {{ $builder }} struct { config mutation *{{ $.MutationName }} hooks []Hook } {{ with extend $ "Builder" $builder }} {{ template "setter" . }} {{ end }} // Save creates the {{ $.Name }} in the database. func ({{ $receiver }} *{{ $builder }}) Save(ctx context.Context) (*{{ $.Name }}, error) { var ( err error node *{{ $.Name }} ) {{- if $.HasDefault }} {{ $receiver }}.defaults() {{- end }} if len({{ $receiver }}.hooks) == 0 { if err = {{ $receiver }}.check(); err != nil { return nil, err } 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 err = {{ $receiver }}.check(); err != nil { return nil, err } {{ $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 calls Save and panics if Save returns an error. func ({{ $receiver }} *{{ $builder }}) SaveX(ctx context.Context) *{{ $.Name }} { v, err := {{ $receiver }}.Save(ctx) if err != nil { panic(err) } return v } {{- $fields := $.Fields }}{{ if $.ID.UserDefined }}{{ $fields = append $fields $.ID }}{{ end }} {{ if $.HasDefault }} // defaults sets the default values of the builder before save. func ({{ $receiver }} *{{ $builder }}) defaults() { {{- range $f := $fields }} {{- if or $f.Default }} if _, ok := {{ $mutation }}.{{ $f.MutationGet }}(); !ok { v := {{ $.Package }}.{{ $f.DefaultName }}{{ if $f.DefaultFunc }}(){{ end }} {{ $mutation }}.Set{{ $f.StructField }}(v) } {{- end }} {{- end }} } {{ end }} // check runs all checks and user-defined validators on the builder. func ({{ $receiver }} *{{ $builder }}) check() error { {{- range $f := $fields }} {{- if and (not $f.Optional) (ne $f.Name $.ID.Name) }} if _, ok := {{ $mutation }}.{{ $f.MutationGet }}(); !ok { return &ValidationError{Name: "{{ $f.Name }}", err: errors.New("{{ $pkg }}: missing required field \"{{ $f.Name }}\"")} } {{- end }} {{- with or $f.Validators $f.IsEnum }} 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 not $e.Optional }} {{- if $e.Unique }} if _, ok := {{ $mutation }}.{{ $e.StructField }}ID(); !ok { {{- else }} if len({{ $mutation }}.{{ $e.StructField }}IDs()) == 0 { {{- end }} return &ValidationError{Name: "{{ $e.Name }}", err: errors.New("{{ $pkg }}: missing required edge \"{{ $e.Name }}\"")} } {{- end }} {{- end }} return nil } {{ with extend $ "Builder" $builder }} {{ $tmpl := printf "dialect/%s/create" $.Storage }} {{ xtemplate $tmpl . }} {{ end }} {{- /* Support adding create methods by global templates. */}} {{- with $tmpls := matchTemplate "create/additional/*" }} {{- range $tmpl := $tmpls }} {{ xtemplate $tmpl $ }} {{- end }} {{- end }} {{ $bulk := printf "%sCreateBulk" (pascal $.Name) }} {{ $receiver = receiver $bulk }} // {{ $bulk }} is the builder for creating many {{ $.Name }} entities in bulk. type {{ $bulk }} struct { config builders []*{{ $builder }} } {{/* If the storage driver supports bulk creation */}} {{ $tmpl := printf "dialect/%s/create_bulk" $.Storage }} {{ if hasTemplate $tmpl }} {{ with extend $ "Builder" $bulk "Receiver" $receiver }} {{ xtemplate $tmpl . }} {{ end }} {{ end }} {{ end }}