mirror of
https://github.com/ent/ent.git
synced 2026-05-24 09:31:56 +03:00
ent/field: add update_default option time field
Reviewed By: alexsn Differential Revision: D17070907 fbshipit-source-id: 63c9ce75c58e524044c38f9461cb04e8e45c8017
This commit is contained in:
committed by
Facebook Github Bot
parent
bd07c86b60
commit
772b8a33f8
File diff suppressed because one or more lines are too long
@@ -26,9 +26,9 @@ type {{ $builder }} struct {
|
||||
// Save creates the {{ $.Name }} in the database.
|
||||
func ({{ $receiver }} *{{ $builder }}) Save(ctx context.Context) (*{{ $.Name }}, error) {
|
||||
{{ range $_, $f := $.Fields -}}
|
||||
{{- if or $f.HasDefault (not $f.Optional) -}}
|
||||
{{- if or $f.Default (not $f.Optional) -}}
|
||||
if {{ $receiver }}.{{ $f.StructField }} == nil {
|
||||
{{ if $f.HasDefault -}}
|
||||
{{ if $f.Default -}}
|
||||
v := {{ $.Package }}.{{ $f.DefaultName }}{{ if $f.IsTime }}(){{ end }}
|
||||
{{ $receiver }}.{{ $f.StructField }} = &v
|
||||
{{ else -}}
|
||||
@@ -38,7 +38,7 @@ func ({{ $receiver }} *{{ $builder }}) Save(ctx context.Context) (*{{ $.Name }},
|
||||
{{ end -}}
|
||||
{{ with $f.Validators -}}
|
||||
{{/* add nullable check only for optional fields without default value */ -}}
|
||||
{{ $nullable := and $f.Optional (not $f.HasDefault) -}}
|
||||
{{ $nullable := and $f.Optional (not $f.Default) -}}
|
||||
{{- if $nullable }} if {{ $receiver }}.{{ $f.StructField }} != nil { {{ end -}}
|
||||
if err := {{ $.Package }}.{{ $f.Validator }}(*{{ $receiver }}.{{ $f.StructField }}); err != nil {
|
||||
return nil, fmt.Errorf("{{ $pkg }}: validator failed for field \"{{ $f.Name }}\": %v", err)
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
{{ $builder := pascal $.Scope.Builder }}
|
||||
{{ $receiver := receiver $builder }}
|
||||
{{ $fields := $.Fields }}
|
||||
{{ $updater := false }}
|
||||
{{- if or (hasSuffix $builder "Update") (hasSuffix $builder "UpdateOne") }}
|
||||
{{ $updater := true }}
|
||||
{{ $fields = $.MutableFields }}
|
||||
{{- end }}
|
||||
|
||||
@@ -15,7 +17,7 @@
|
||||
return {{ $receiver }}
|
||||
}
|
||||
{{/* avoid generting nillable setters for slices because the nil value for slice is valid */}}
|
||||
{{ if and (not $f.Type.Slice) (or $f.Optional $f.Nillable $f.HasDefault) }}
|
||||
{{ if and (not $f.Type.Slice) (or $f.Optional $f.Default) (not (and $updater $f.UpdateDefault)) }}
|
||||
{{ $nillableFunc := print "SetNillable" (pascal $f.Name) }}
|
||||
// {{ $nillableFunc }} sets the {{ $f.Name }} field if the given value is not nil.
|
||||
func ({{ $receiver }} *{{ $builder }}) {{ $nillableFunc }}({{ $p }} *{{ $f.Type }}) *{{ $builder }} {
|
||||
|
||||
@@ -33,7 +33,7 @@ func ({{ $receiver}} *{{ $builder }}) Where(ps ...predicate.{{ $.Name }}) *{{ $b
|
||||
// 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/validators" . }}
|
||||
{{ template "update/save" . }}
|
||||
{{- end -}}
|
||||
{{- if $multistorage -}}
|
||||
switch {{ $receiver }}.driver.Dialect() {
|
||||
@@ -100,7 +100,7 @@ type {{ $onebuilder }} struct {
|
||||
// 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/validators" . }}
|
||||
{{ template "update/save" . }}
|
||||
{{- end -}}
|
||||
{{- if $multistorage -}}
|
||||
switch {{ $receiver }}.driver.Dialect() {
|
||||
@@ -149,8 +149,10 @@ func ({{ $receiver }} *{{ $onebuilder }}) ExecX(ctx context.Context) {
|
||||
|
||||
{{/* shared struct fields between the two updaters */}}
|
||||
{{ define "update/fields"}}
|
||||
{{ range $_, $f := $.MutableFields }}
|
||||
{{- $f.StructField }} *{{ $f.Type }}
|
||||
{{ range $_, $f := $.Fields }}
|
||||
{{- if or (not $f.Immutable) $f.UpdateDefault }}
|
||||
{{- $f.StructField }} *{{ $f.Type }}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
{{- range $_, $e := $.Edges }}
|
||||
{{- $e.StructField }} map[{{ $.ID.Type }}]struct{}
|
||||
@@ -203,12 +205,18 @@ func ({{ $receiver }} *{{ $onebuilder }}) ExecX(ctx context.Context) {
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{/* shared templates for validators. */}}
|
||||
{{ define "update/validators" }}
|
||||
{{/* shared template for the save method of the 2 builders */}}
|
||||
{{ define "update/save" }}
|
||||
{{- $pkg := .Scope.Package -}}
|
||||
{{- $zero := .Scope.ZeroValue }}
|
||||
{{- $receiver := .Scope.Receiver -}}
|
||||
{{- range $_, $f := $.Fields -}}
|
||||
{{- if $f.UpdateDefault -}}
|
||||
if {{ $receiver }}.{{ $f.StructField }} == nil {
|
||||
v := {{ $.Package }}.{{ $f.UpdateDefaultName }}{{ if $f.IsTime }}(){{ end }}
|
||||
{{ $receiver }}.{{ $f.StructField }} = &v
|
||||
}
|
||||
{{ end -}}
|
||||
{{ with $f.Validators -}}
|
||||
if {{ $receiver }}.{{ $f.StructField }} != nil {
|
||||
if err := {{ $.Package }}.{{ $f.Validator }}(*{{ $receiver }}.{{ $f.StructField }}); err != nil {
|
||||
|
||||
@@ -49,7 +49,7 @@ func ({{ $receiver }} *{{ $slice }}) FromResponse(res *gremlin.Response) error {
|
||||
*{{ $receiver }} = append(*{{ $receiver }}, &{{ $.Name }}{
|
||||
ID: v.ID,
|
||||
{{ range $_, $f := $.Fields }}
|
||||
{{- pascal $f.Name }}: {{- if $f.IsTime }}time.Unix(v.{{ pascal $f.Name }}, 0) {{ else }}v.{{ pascal $f.Name }}{{ end }},
|
||||
{{- pascal $f.Name }}: {{- if $f.IsTime }}time.Unix(0, v.{{ pascal $f.Name }}) {{ else }}v.{{ pascal $f.Name }}{{ end }},
|
||||
{{ end -}}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -50,16 +50,18 @@ func ({{ $receiver }} *{{ $builder }}) gremlin({{ if $one }}id {{ $.ID.Type }}{{
|
||||
{{ end }}
|
||||
trs []*dsl.Traversal
|
||||
)
|
||||
{{- range $_, $f := $.MutableFields }}
|
||||
if {{ $receiver }}.{{ $f.StructField }} != nil {
|
||||
{{- if $f.Unique }}
|
||||
constraints = append(constraints, &constraint{
|
||||
pred: g.V().Has({{ $.Package }}.Label, {{ $.Package }}.{{ $f.Constant }}, *{{ $receiver }}.{{ $f.StructField }}).Count(),
|
||||
test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField({{ $.Package }}.Label, {{ $.Package }}.{{ $f.Constant }}, *{{ $receiver }}.{{ $f.StructField }})),
|
||||
})
|
||||
{{- range $_, $f := $.Fields }}
|
||||
{{- if or (not $f.Immutable) $f.UpdateDefault }}
|
||||
if {{ $receiver }}.{{ $f.StructField }} != nil {
|
||||
{{- if $f.Unique }}
|
||||
constraints = append(constraints, &constraint{
|
||||
pred: g.V().Has({{ $.Package }}.Label, {{ $.Package }}.{{ $f.Constant }}, *{{ $receiver }}.{{ $f.StructField }}).Count(),
|
||||
test: __.Is(p.NEQ(0)).Constant(NewErrUniqueField({{ $.Package }}.Label, {{ $.Package }}.{{ $f.Constant }}, *{{ $receiver }}.{{ $f.StructField }})),
|
||||
})
|
||||
{{- end }}
|
||||
v.Property(dsl.Single, {{ $.Package }}.{{ $f.Constant }}, *{{ $receiver }}.{{ $f.StructField }})
|
||||
}
|
||||
{{- end }}
|
||||
v.Property(dsl.Single, {{ $.Package }}.{{ $f.Constant }}, *{{ $receiver }}.{{ $f.StructField }})
|
||||
}
|
||||
{{- end }}
|
||||
{{- range $_, $e := $.Edges }}
|
||||
{{- $direction := "In" }}
|
||||
|
||||
@@ -60,18 +60,20 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
|
||||
res sql.Result
|
||||
builder = sql.Update({{ $.Package }}.Table).Where(sql.InInts({{ $.Package }}.{{ $.ID.Constant }}, ids...))
|
||||
)
|
||||
{{- range $_, $f := $.MutableFields }}
|
||||
if {{ $receiver }}.{{ $f.StructField }} != nil {
|
||||
update = true
|
||||
builder.Set({{ $.Package }}.{{ $f.Constant }}, *{{ $receiver }}.{{ $f.StructField }})
|
||||
{{- if $one }}
|
||||
{{- if $f.Nillable }}
|
||||
{{ $.Receiver }}.{{ pascal $f.Name }} = {{ $receiver }}.{{ $f.StructField }}
|
||||
{{- else }}
|
||||
{{ $.Receiver }}.{{ pascal $f.Name }} = *{{ $receiver }}.{{ $f.StructField }}
|
||||
{{- range $_, $f := $.Fields }}
|
||||
{{- if or (not $f.Immutable) $f.UpdateDefault }}
|
||||
if {{ $receiver }}.{{ $f.StructField }} != nil {
|
||||
update = true
|
||||
builder.Set({{ $.Package }}.{{ $f.Constant }}, *{{ $receiver }}.{{ $f.StructField }})
|
||||
{{- if $one }}
|
||||
{{- if $f.Nillable }}
|
||||
{{ $.Receiver }}.{{ pascal $f.Name }} = {{ $receiver }}.{{ $f.StructField }}
|
||||
{{- else }}
|
||||
{{ $.Receiver }}.{{ pascal $f.Name }} = *{{ $receiver }}.{{ $f.StructField }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
if update {
|
||||
query, args := builder.Query()
|
||||
|
||||
@@ -33,15 +33,20 @@ var (
|
||||
fields = {{ base $.Schema }}.{{ $.Name }}{}.Fields()
|
||||
{{ range $i, $f := $.Fields -}}
|
||||
{{- $desc := print "desc" (pascal $f.Name) -}}
|
||||
{{ if or $f.HasDefault $f.Validators -}}
|
||||
{{ if or $f.Default $f.UpdateDefault $f.Validators -}}
|
||||
// {{ $desc }} is the schema descriptor for {{ $f.Name }} field.
|
||||
{{ $desc }} = fields[{{ $i }}].Descriptor()
|
||||
{{ end -}}
|
||||
{{ if $f.HasDefault }}
|
||||
{{ if $f.Default }}
|
||||
{{- $default := $f.DefaultName -}}
|
||||
// {{ $default }} holds the default value for the {{ $f.Name }} field.
|
||||
// {{ $default }} holds the default value on creation for the {{ $f.Name }} field.
|
||||
{{ $default }} = {{ $desc }}.Default.({{ if $f.IsTime }}func() {{ end }}{{ $f.Type }})
|
||||
{{ end -}}
|
||||
{{ if $f.UpdateDefault }}
|
||||
{{- $default := $f.UpdateDefaultName -}}
|
||||
// {{ $default }} holds the default value on update for the {{ $f.Name }} field.
|
||||
{{ $default }} = {{ $desc }}.UpdateDefault.({{ if $f.IsTime }}func() {{ end }}{{ $f.Type }})
|
||||
{{ end -}}
|
||||
{{ with $f.Validators -}}
|
||||
{{ $name := $f.Validator -}}
|
||||
{{ $type := printf "func (%s) error" $f.Type -}}
|
||||
|
||||
@@ -52,8 +52,10 @@ type (
|
||||
// Nillable indicates that this field can be null in the
|
||||
// database and pointer in the generated entities.
|
||||
Nillable bool
|
||||
// HasDefault indicates if this field a default value.
|
||||
HasDefault bool
|
||||
// Default indicates if this field has a default value for creation.
|
||||
Default bool
|
||||
// UpdateDefault indicates if this field has a default value for update.
|
||||
UpdateDefault bool
|
||||
// Immutable indicates is this field cannot be updated.
|
||||
Immutable bool
|
||||
// StructTag of the field. default to "json".
|
||||
@@ -142,16 +144,17 @@ func NewType(c Config, schema *load.Schema) (*Type, error) {
|
||||
return nil, fmt.Errorf("field %q redeclared for type %q", f.Name, typ.Name)
|
||||
}
|
||||
typ.Fields[i] = &Field{
|
||||
def: f,
|
||||
Name: f.Name,
|
||||
Type: f.Type,
|
||||
Unique: f.Unique,
|
||||
Nillable: f.Nillable,
|
||||
Optional: f.Optional,
|
||||
HasDefault: f.Default,
|
||||
Immutable: f.Immutable,
|
||||
StructTag: structTag(f.Name, f.Tag),
|
||||
Validators: f.Validators,
|
||||
def: f,
|
||||
Name: f.Name,
|
||||
Type: f.Type,
|
||||
Unique: f.Unique,
|
||||
Nillable: f.Nillable,
|
||||
Optional: f.Optional,
|
||||
Default: f.Default,
|
||||
UpdateDefault: f.UpdateDefault,
|
||||
Immutable: f.Immutable,
|
||||
StructTag: structTag(f.Name, f.Tag),
|
||||
Validators: f.Validators,
|
||||
}
|
||||
typ.fields[f.Name] = typ.Fields[i]
|
||||
}
|
||||
@@ -194,10 +197,20 @@ func (t Type) HasValidators() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// HasDefault indicates if any of this type's fields has default value.
|
||||
// HasDefault indicates if any of this type's fields has default value on creation.
|
||||
func (t Type) HasDefault() bool {
|
||||
for _, f := range t.Fields {
|
||||
if f.HasDefault {
|
||||
if f.Default {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HasUpdateDefault indicates if any of this type's fields has default value on update.
|
||||
func (t Type) HasUpdateDefault() bool {
|
||||
for _, f := range t.Fields {
|
||||
if f.Default {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -331,6 +344,9 @@ func (f Field) Constant() string { return "Field" + pascal(f.Name) }
|
||||
// DefaultName returns the variable name of the default value of this field.
|
||||
func (f Field) DefaultName() string { return "Default" + pascal(f.Name) }
|
||||
|
||||
// UpdateDefaultName returns the variable name of the update default value of this field.
|
||||
func (f Field) UpdateDefaultName() string { return "Update" + f.DefaultName() }
|
||||
|
||||
// StructField returns the struct member of the field.
|
||||
func (f Field) StructField() string {
|
||||
if token.Lookup(f.Name).IsKeyword() {
|
||||
@@ -404,7 +420,7 @@ func (f Field) Column() *schema.Column {
|
||||
c.Charset = *f.def.Charset
|
||||
}
|
||||
}
|
||||
if f.HasDefault && !f.IsTime() {
|
||||
if f.Default && !f.IsTime() {
|
||||
// since this column is used only for codegen, the actual default
|
||||
// value is imported by the migrate package and used directly.
|
||||
c.Default = true
|
||||
|
||||
Reference in New Issue
Block a user