Skip to content

Commit

Permalink
schema/field: fallback to native validator if not configured one (ent…
Browse files Browse the repository at this point in the history
  • Loading branch information
a8m authored Mar 1, 2023
1 parent 89e2d52 commit 9517200
Show file tree
Hide file tree
Showing 21 changed files with 89 additions and 88 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ jobs:
restore-keys: |
${{ runner.os }}-go-
- name: Run go generate
run: go generate ./...
run: go generate ./... && go mod tidy
- name: Run go generate on examples directory
working-directory: examples
run: go generate ./...
run: go generate ./... && go mod tidy
- name: Check generated files
run: |
status=$(git status --porcelain)
Expand Down
3 changes: 2 additions & 1 deletion doc/md/schema-fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ and for time fields, the type is `time.Time`. The `GoType` method provides an op
default ent type with a custom one.

The custom type must be either a type that is convertible to the Go basic type, or a type that implements the
[ValueScanner](https://pkg.go.dev/entgo.io/ent/schema/field?tab=doc#ValueScanner) interface.
[ValueScanner](https://pkg.go.dev/entgo.io/ent/schema/field?tab=doc#ValueScanner) interface. Also, if the provided
type implements the Validator interface and no validators have been set, the type validator will be used.


```go
Expand Down
6 changes: 3 additions & 3 deletions entc/gen/template/builder/create.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,10 @@ func ({{ $receiver }} *{{ $builder }}) check() error {
{{- end }}
{{- end }}
{{- end }}
{{- with or $f.Validators $f.IsEnum }}
{{- $isValidator := and ($f.HasGoType) ($f.Type.Validator) }}
{{- with or $f.Validators $f.IsEnum $isValidator }}
if v, ok := {{ $mutation }}.{{ $f.MutationGet }}(); ok {
{{- $basic := $f.BasicType "v" }}
if err := {{ $.Package }}.{{ $f.Validator }}({{ $basic }}); err != nil {
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)}
}
}
Expand Down
6 changes: 3 additions & 3 deletions entc/gen/template/builder/update.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,10 @@ func ({{ $receiver }} *{{ $onebuilder }}) ExecX(ctx context.Context) {
// 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) }}
{{- $isValidator := and ($f.HasGoType) ($f.Type.Validator) }}
{{- with and (not $f.Immutable) (or $f.Validators $f.IsEnum $isValidator) }}
if v, ok := {{ $mutation }}.{{ $f.MutationGet }}(); ok {
{{- $basic := $f.BasicType "v" }}
if err := {{ $.Package }}.{{ $f.Validator }}({{ $basic }}); err != nil {
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)}
}
}
Expand Down
2 changes: 0 additions & 2 deletions entc/integration/ent/runtime.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions entc/integration/ent/schema/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ func (Task) Fields() []ent.Field {
return []ent.Field{
field.Int("priority").
GoType(task.Priority(0)).
Default(int(task.PriorityMid)).
Validate(func(i int) error {
return task.Priority(i).Validate()
}),
Default(int(task.PriorityMid)),
field.JSON("priorities", map[string]task.Priority{}).
Optional(),
field.Time("created_at").
Expand Down
2 changes: 0 additions & 2 deletions entc/integration/ent/task/task.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/ent/task_create.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 0 additions & 26 deletions entc/integration/ent/task_update.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions entc/integration/gremlin/ent/runtime.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions entc/integration/gremlin/ent/task/task.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/gremlin/ent/task_create.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 0 additions & 27 deletions entc/integration/gremlin/ent/task_update.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.19
replace entgo.io/ent => ../

require (
ariga.io/atlas v0.9.1-0.20230212142236-47ec3817e19f
ariga.io/atlas v0.9.1
entgo.io/ent v0.0.0-00010101000000-000000000000
github.com/google/uuid v1.3.0
github.com/mattn/go-sqlite3 v1.14.16
Expand Down
11 changes: 3 additions & 8 deletions examples/go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ariga.io/atlas v0.9.1-0.20230212142236-47ec3817e19f h1:m1qkdlpykdsyOT1MDi+x/j5bCP9CFySWFmQmKcrtUQE=
ariga.io/atlas v0.9.1-0.20230212142236-47ec3817e19f/go.mod h1:T230JFcENj4ZZzMkZrXFDSkv+2kXkUgpJ5FQQ5hMcKU=
ariga.io/atlas v0.9.1 h1:EpoPMnwsQG0vn9c0sYExpwSYtr7bvuSUXzQclU2pMjc=
ariga.io/atlas v0.9.1/go.mod h1:T230JFcENj4ZZzMkZrXFDSkv+2kXkUgpJ5FQQ5hMcKU=
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
Expand Down Expand Up @@ -1313,7 +1313,6 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
Expand Down Expand Up @@ -1390,7 +1389,6 @@ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQ
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
Expand Down Expand Up @@ -1605,13 +1603,11 @@ github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKv
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
Expand All @@ -1635,8 +1631,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
Expand Down Expand Up @@ -2276,7 +2272,6 @@ golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.6.1-0.20230222164832-25d2519c8696 h1:8985/C5IvACpd9DDXckSnjSBLKDgbxXiyODgi94zOPM=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module entgo.io/ent
go 1.19

require (
ariga.io/atlas v0.9.1-0.20230212142236-47ec3817e19f
ariga.io/atlas v0.9.1
github.com/DATA-DOG/go-sqlmock v1.5.0
github.com/go-openapi/inflect v0.19.0
github.com/go-sql-driver/mysql v1.7.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ariga.io/atlas v0.9.1-0.20230212142236-47ec3817e19f h1:m1qkdlpykdsyOT1MDi+x/j5bCP9CFySWFmQmKcrtUQE=
ariga.io/atlas v0.9.1-0.20230212142236-47ec3817e19f/go.mod h1:T230JFcENj4ZZzMkZrXFDSkv+2kXkUgpJ5FQQ5hMcKU=
ariga.io/atlas v0.9.1 h1:EpoPMnwsQG0vn9c0sYExpwSYtr7bvuSUXzQclU2pMjc=
ariga.io/atlas v0.9.1/go.mod h1:T230JFcENj4ZZzMkZrXFDSkv+2kXkUgpJ5FQQ5hMcKU=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
Expand Down
22 changes: 22 additions & 0 deletions schema/field/field.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ func (b *stringBuilder) SchemaType(types map[string]string) *stringBuilder {
}

// GoType overrides the default Go type with a custom one.
// If the provided type implements the Validator interface
// and no validators have been set, the type validator will
// be used.
//
// field.String("dir").
// GoType(http.Dir("dir"))
Expand Down Expand Up @@ -397,6 +400,9 @@ func (b *timeBuilder) StorageKey(key string) *timeBuilder {
}

// GoType overrides the default Go type with a custom one.
// If the provided type implements the Validator interface
// and no validators have been set, the type validator will
// be used.
//
// field.Time("deleted_at").
// GoType(&sql.NullTime{})
Expand Down Expand Up @@ -489,6 +495,9 @@ func (b *boolBuilder) StorageKey(key string) *boolBuilder {
}

// GoType overrides the default Go type with a custom one.
// If the provided type implements the Validator interface
// and no validators have been set, the type validator will
// be used.
//
// field.Bool("deleted").
// GoType(&sql.NullBool{})
Expand Down Expand Up @@ -637,6 +646,9 @@ func (b *bytesBuilder) StorageKey(key string) *bytesBuilder {
}

// GoType overrides the default Go type with a custom one.
// If the provided type implements the Validator interface
// and no validators have been set, the type validator will
// be used.
//
// field.Bytes("ip").
// GoType(net.IP("127.0.0.1"))
Expand Down Expand Up @@ -876,6 +888,9 @@ type EnumValues interface {
}

// GoType overrides the default Go type with a custom one.
// If the provided type implements the Validator interface
// and no validators have been set, the type validator will
// be used.
//
// field.Enum("enum").
// GoType(role.Enum("role"))
Expand Down Expand Up @@ -1228,6 +1243,7 @@ var (
stringType = reflect.TypeOf("")
valuerType = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
valueScannerType = reflect.TypeOf((*ValueScanner)(nil)).Elem()
validatorType = reflect.TypeOf((*Validator)(nil)).Elem()
)

// ValueScanner is the interface that groups the Value and the Scan methods.
Expand All @@ -1236,6 +1252,12 @@ type ValueScanner interface {
sql.Scanner
}

// Validator interface wraps the Validate method. Custom GoTypes with
// this method will be validated when the entity is created or updated.
type Validator interface {
Validate() error
}

// indirect returns the type at the end of indirection.
func indirect(t reflect.Type) reflect.Type {
for t.Kind() == reflect.Ptr {
Expand Down
6 changes: 6 additions & 0 deletions schema/field/internal/numeric.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ func (b *{{ $builder }}) SchemaType(types map[string]string) *{{ $builder }} {

{{ $tt := title $t.String }}
// GoType overrides the default Go type with a custom one.
// If the provided type implements the Validator interface
// and no validators have been set, the type validator will
// be used.
//
// field.{{ $tt }}("{{ $t }}").
// GoType(pkg.{{ $tt }}(0))
Expand Down Expand Up @@ -358,6 +361,9 @@ func (b *{{ $builder }}) SchemaType(types map[string]string) *{{ $builder }} {

{{ $tt := title $t.String }}
// GoType overrides the default Go type with a custom one.
// If the provided type implements the Validator interface
// and no validators have been set, the type validator will
// be used.
//
// field.{{ $tt }}("{{ $t }}").
// GoType(pkg.{{ $tt }}(0))
Expand Down
Loading

0 comments on commit 9517200

Please sign in to comment.