{{/* 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. */}} {{/* gotype: entgo.io/ent/entc/gen.Type */}} {{ define "create" }} {{ $pkg := base $.Config.Package }} {{ $runtimeRequired := or $.NumHooks $.NumPolicy }} {{ template "header" $ }} {{ with extend $ "Imports" $.SiblingImports }} {{ template "import" . }} {{ end }} {{ $builder := $.CreateName }} {{ $receiver := $.CreateReceiver }} {{ $mutation := print $receiver ".mutation" }} // {{ $builder }} is the builder for creating a {{ $.Name }} entity. type {{ $builder }} struct { config mutation *{{ $.MutationName }} hooks []Hook {{- /* Additional fields to add to the builder. */}} {{- $tmpl := printf "dialect/%s/create/fields" $.Storage }} {{- if hasTemplate $tmpl }} {{- xtemplate $tmpl . }} {{- end }} } {{ with extend $ "Receiver" $receiver "Builder" $builder }} {{ template "setter" . }} {{ end }} // Save creates the {{ $.Name }} in the database. func ({{ $receiver }} *{{ $builder }}) Save(ctx context.Context) (*{{ $.Name }}, error) { {{- if $.HasDefault }} {{- if $runtimeRequired }} if err := {{ $receiver }}.defaults(); err != nil { return nil, err } {{- else }} {{ $receiver }}.defaults() {{- end }} {{- end }} return withHooks(ctx, {{ $receiver }}.{{ $.Storage }}Save, {{ $mutation }}, {{ $receiver }}.hooks) } // 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 } // 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) } } {{- $fields := $.Fields }}{{ if $.HasOneFieldID }}{{ if $.ID.UserDefined }}{{ $fields = append $fields $.ID }}{{ end }}{{ end }} {{ if $.HasDefault }} // defaults sets the default values of the builder before save. func ({{ $receiver }} *{{ $builder }}) defaults() {{ if $runtimeRequired }}error{{ end }}{ {{- range $f := $fields }} {{- if $f.Default }} if _, ok := {{ $mutation }}.{{ $f.MutationGet }}(); !ok { {{- if and $runtimeRequired $f.DefaultFunc }} if {{ $.Package }}.{{ $f.DefaultName }} == nil { return fmt.Errorf("{{ $pkg }}: uninitialized {{ $.Package }}.{{ $f.DefaultName }} (forgotten import {{ $pkg }}/runtime?)") } {{- end }} v := {{ $.Package }}.{{ $f.DefaultName }}{{ if $f.DefaultFunc }}(){{ end }} {{ $mutation }}.{{ $f.MutationSet }}(v) } {{- end }} {{- end }} {{- if $runtimeRequired }} return nil {{- end }} } {{ end }} // check runs all checks and user-defined validators on the builder. func ({{ $receiver }} *{{ $builder }}) check() error { {{- range $f := $fields }} {{- $skip := false }}{{ if $.HasOneFieldID }}{{ if eq $f.Name $.ID.Name }}{{ $skip = true }}{{ end }}{{ end }} {{- if and (not $f.Optional) (not $skip) }} {{- $dialects := $f.RequiredFor }} {{- $n := len $dialects }} {{- if $n }} {{- $partially := ne $n (len $.Config.Storage.Dialects) }} {{- if $partially }} switch {{ $receiver }}.driver.Dialect() { case {{ join $dialects ", " }}: {{- end }} if _, ok := {{ $mutation }}.{{ $f.MutationGet }}(); !ok { return &ValidationError{Name: "{{ $f.Name }}", err: errors.New(`{{ $pkg }}: missing required field "{{ $.Name }}.{{ $f.Name }}"`)} } {{- if $partially }} } {{- end }} {{- end }} {{- end }} {{- $isValidator := and ($f.HasGoType) ($f.Type.Validator) }} {{- with or $f.Validators $f.IsEnum $isValidator }} if v, ok := {{ $mutation }}.{{ $f.MutationGet }}(); ok { if err := {{ if or $f.Validators $f.IsEnum }}{{ $.Package }}.{{ $f.Validator }}({{ $f.BasicType "v" }}){{ else }}v.Validate(){{ end }}; err != nil { return &ValidationError{Name: "{{ $f.Name }}", err: fmt.Errorf(`{{ $pkg }}: validator failed for field "{{ $.Name }}.{{ $f.Name }}": %w`, err)} } } {{- end }} {{- end }} {{- range $e := $.EdgesWithID }} {{- if not $e.Optional }} if len({{ $mutation }}.{{ $e.StructField }}IDs()) == 0 { return &ValidationError{Name: "{{ $e.Name }}", err: errors.New(`{{ $pkg }}: missing required edge "{{ $.Name }}.{{ $e.Name }}"`)} } {{- end }} {{- end }} return nil } {{ with extend $ "Receiver" $receiver "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 := $.CreateBulkName }} {{ $receiver = $.CreateBulReceiver }} // {{ $bulk }} is the builder for creating many {{ $.Name }} entities in bulk. type {{ $bulk }} struct { config err error builders []*{{ $builder }} {{- /* Additional fields to add to the builder. */}} {{- $tmpl = printf "dialect/%s/create_bulk/fields" $.Storage }} {{- if hasTemplate $tmpl }} {{- xtemplate $tmpl . }} {{- end }} } {{/* If the storage driver supports bulk creation */}} {{ $tmpl = printf "dialect/%s/create_bulk" $.Storage }} {{ if hasTemplate $tmpl }} {{ with extend $ "Receiver" $receiver "Builder" $bulk }} {{ xtemplate $tmpl . }} {{ end }} {{ end }} {{ end }}