schema/field: add builder per numeric type

Summary: Pull Request resolved: https://github.com/facebookincubator/ent/pull/21

Reviewed By: alexsn

Differential Revision: D16936906

fbshipit-source-id: 06f5721ed0088107cf42382731f8b7282f22eef7
This commit is contained in:
Ariel Mashraki
2019-08-21 07:58:44 -07:00
committed by Facebook Github Bot
parent 8b345d94bb
commit f519a5465e
14 changed files with 1876 additions and 390 deletions

View File

@@ -122,24 +122,6 @@ type Field struct {
validators []interface{}
}
// Int returns a new Field with type int.
func Int(name string) *intBuilder { return &intBuilder{Field{typ: TypeInt, name: name}} }
// Int8 returns a new Field with type int8.
func Int8(name string) *intBuilder { return &intBuilder{Field{typ: TypeInt8, name: name}} }
// Int16 returns a new Field with type int16.
func Int16(name string) *intBuilder { return &intBuilder{Field{typ: TypeInt16, name: name}} }
// Int32 returns a new Field with type int32.
func Int32(name string) *intBuilder { return &intBuilder{Field{typ: TypeInt32, name: name}} }
// Int64 returns a new Field with type int64.
func Int64(name string) *intBuilder { return &intBuilder{Field{typ: TypeInt64, name: name}} }
// Float returns a new Field with type float.
func Float(name string) *floatBuilder { return &floatBuilder{Field{typ: TypeFloat64, name: name}} }
// String returns a new Field with type string.
func String(name string) *stringBuilder { return &stringBuilder{Field{typ: TypeString, name: name}} }
@@ -189,200 +171,6 @@ func (f Field) Validators() []interface{} { return f.validators }
// Tag returns the struct tag of the field.
func (f Field) Tag() string { return f.tag }
// intBuilder is the builder for int field.
type intBuilder struct {
Field
}
// Unique makes the field unique within all vertices of this type.
func (b *intBuilder) Unique() *intBuilder {
b.unique = true
return b
}
// Range adds a range validator for this field where the given value needs to be in the range of [i, j].
func (b *intBuilder) Range(i, j int) *intBuilder {
b.validators = append(b.validators, func(v int) error {
if v < i || v > j {
return errors.New("value out of range")
}
return nil
})
return b
}
// Min adds a minimum value validator for this field. Operation fails if the validator fails.
func (b *intBuilder) Min(i int) *intBuilder {
b.validators = append(b.validators, func(v int) error {
if v < i {
return errors.New("value out of range")
}
return nil
})
return b
}
// Max adds a maximum value validator for this field. Operation fails if the validator fails.
func (b *intBuilder) Max(i int) *intBuilder {
b.validators = append(b.validators, func(v int) error {
if v > i {
return errors.New("value out of range")
}
return nil
})
return b
}
// Positive adds a minimum value validator with the value of 1. Operation fails if the validator fails.
func (b *intBuilder) Positive() *intBuilder {
return b.Min(1)
}
// Negative adds a maximum value validator with the value of -1. Operation fails if the validator fails.
func (b *intBuilder) Negative() *intBuilder {
return b.Max(-1)
}
// Default sets the default value of the field.
func (b *intBuilder) Default(i int) *intBuilder {
b.value = i
return b
}
// Nillable indicates that this field is a nillable.
// Unlike "Optional" only fields, "Nillable" fields are pointers in the generated field.
func (b *intBuilder) Nillable() *intBuilder {
b.nillable = true
return b
}
// Comment sets the comment of the field.
func (b *intBuilder) Comment(c string) *intBuilder {
return b
}
// Optional indicates that this field is optional on create.
// Unlike edges, fields are required by default.
func (b *intBuilder) Optional() *intBuilder {
b.optional = true
return b
}
// Immutable indicates that this field cannot be updated.
func (b *intBuilder) Immutable() *intBuilder {
b.immutable = true
return b
}
// StructTag sets the struct tag of the field.
func (b *intBuilder) StructTag(s string) *intBuilder {
b.tag = s
return b
}
// Validate adds a validator for this field. Operation fails if the validation fails.
func (b *intBuilder) Validate(fn func(int) error) *intBuilder {
b.validators = append(b.validators, fn)
return b
}
// floatBuilder is the builder for float fields.
type floatBuilder struct {
Field
}
// Unique makes the field unique within all vertices of this type.
func (b *floatBuilder) Unique() *floatBuilder {
b.unique = true
return b
}
// Range adds a range validator for this field where the given value needs to be in the range of [i, j].
func (b *floatBuilder) Range(i, j float64) *floatBuilder {
b.validators = append(b.validators, func(v float64) error {
if v < i || v > j {
return errors.New("value out of range")
}
return nil
})
return b
}
// Min adds a minimum value validator for this field. Operation fails if the validator fails.
func (b *floatBuilder) Min(i float64) *floatBuilder {
b.validators = append(b.validators, func(v float64) error {
if v < i {
return errors.New("value out of range")
}
return nil
})
return b
}
// Max adds a maximum value validator for this field. Operation fails if the validator fails.
func (b *floatBuilder) Max(i float64) *floatBuilder {
b.validators = append(b.validators, func(v float64) error {
if v > i {
return errors.New("value out of range")
}
return nil
})
return b
}
// Positive adds a minimum value validator with the value of 0.000001. Operation fails if the validator fails.
func (b *floatBuilder) Positive() *floatBuilder {
return b.Min(1e-06)
}
// Negative adds a maximum value validator with the value of -0.000001. Operation fails if the validator fails.
func (b *floatBuilder) Negative() *floatBuilder {
return b.Max(-1e-06)
}
// Default sets the default value of the field.
func (b *floatBuilder) Default(i float64) *floatBuilder {
b.value = i
return b
}
// Nillable indicates that this field is a nillable.
// Unlike "Optional" only fields, "Nillable" fields are pointers in the generated field.
func (b *floatBuilder) Nillable() *floatBuilder {
b.nillable = true
return b
}
// Comment sets the comment of the field.
func (b *floatBuilder) Comment(c string) *floatBuilder {
return b
}
// Optional indicates that this field is optional on create.
// Unlike edges, fields are required by default.
func (b *floatBuilder) Optional() *floatBuilder {
b.optional = true
return b
}
// Immutable indicates that this field cannot be updated.
func (b *floatBuilder) Immutable() *floatBuilder {
b.immutable = true
return b
}
// StructTag sets the struct tag of the field.
func (b *floatBuilder) StructTag(s string) *floatBuilder {
b.tag = s
return b
}
// Validate adds a validator for this field. Operation fails if the validation fails.
func (b *floatBuilder) Validate(fn func(float64) error) *floatBuilder {
b.validators = append(b.validators, fn)
return b
}
// stringBuilder is the builder for string fields.
type stringBuilder struct {
Field

52
schema/field/gen/gen.go Normal file
View File

@@ -0,0 +1,52 @@
// gen is a codegen cmd for generating numeric build types from template.
package main
import (
"bytes"
"go/format"
"io/ioutil"
"log"
"strings"
"text/template"
"github.com/facebookincubator/ent/schema/field"
)
func main() {
buf, err := ioutil.ReadFile("gen/numeric.tmpl")
if err != nil {
log.Fatal("reading template file:", err)
}
intTmpl := template.Must(template.New("numeric").
Funcs(template.FuncMap{"title": strings.Title, "hasPrefix": strings.HasPrefix}).
Parse(string(buf)))
b := &bytes.Buffer{}
if err := intTmpl.Execute(b, struct {
Ints, Floats []field.Type
}{
Ints: []field.Type{
field.TypeInt,
field.TypeUint,
field.TypeInt8,
field.TypeInt16,
field.TypeInt32,
field.TypeInt64,
field.TypeUint8,
field.TypeUint16,
field.TypeUint32,
field.TypeUint64,
},
Floats: []field.Type{
field.TypeFloat64,
field.TypeFloat32,
},
}); err != nil {
log.Fatal("executing template:", err)
}
if buf, err = format.Source(b.Bytes()); err != nil {
log.Fatal("formatting output:", err)
}
if err := ioutil.WriteFile("numeric.go", buf, 0644); err != nil {
log.Fatal("writing go file:", err)
}
}

View File

@@ -0,0 +1,225 @@
{{ define "numeric" }}
package field
import "errors"
//go:generate go run gen/gen.go
{{ range $_, $t := $.Ints }}
{{ $title := title $t.String }}
// {{ $title }} returns a new Field with type {{ $t }}.
func {{ $title }}(name string) *{{ $t }}Builder { return &{{ $t }}Builder{Field{typ: Type{{ $title }}, name: name}} }
{{ end }}
// Float returns a new Field with type float64.
func Float(name string) *float64Builder { return &float64Builder{Field{typ: TypeFloat64, name: name}} }
// Float32 returns a new Field with type float32.
func Float32(name string) *float32Builder { return &float32Builder{Field{typ: TypeFloat32, name: name}} }
{{ range $_, $t := $.Ints }}
{{ $builder := printf "%sBuilder" $t }}
// {{ $builder }} is the builder for {{ $t }} field.
type {{ $builder }} struct {
Field
}
// Unique makes the field unique within all vertices of this type.
func (b *{{ $builder }}) Unique() *{{ $builder }} {
b.unique = true
return b
}
// Range adds a range validator for this field where the given value needs to be in the range of [i, j].
func (b *{{ $builder }}) Range(i, j {{ $t }}) *{{ $builder }} {
b.validators = append(b.validators, func(v {{ $t }}) error {
if v < i || v > j {
return errors.New("value out of range")
}
return nil
})
return b
}
// Min adds a minimum value validator for this field. Operation fails if the validator fails.
func (b *{{ $builder }}) Min(i {{ $t }}) *{{ $builder }} {
b.validators = append(b.validators, func(v {{ $t }}) error {
if v < i {
return errors.New("value out of range")
}
return nil
})
return b
}
// Max adds a maximum value validator for this field. Operation fails if the validator fails.
func (b *{{ $builder }}) Max(i {{ $t }}) *{{ $builder }} {
b.validators = append(b.validators, func(v {{ $t }}) error {
if v > i {
return errors.New("value out of range")
}
return nil
})
return b
}
// Positive adds a minimum value validator with the value of 1. Operation fails if the validator fails.
func (b *{{ $builder }}) Positive() *{{ $builder }} {
return b.Min(1)
}
{{ if hasPrefix $t.String "uint" | not }}
// Negative adds a maximum value validator with the value of -1. Operation fails if the validator fails.
func (b *{{ $builder }}) Negative() *{{ $builder }} {
return b.Max(-1)
}
{{ end }}
// Default sets the default value of the field.
func (b *{{ $builder }}) Default(i {{ $t }}) *{{ $builder }} {
b.value = i
return b
}
// Nillable indicates that this field is a nillable.
// Unlike "Optional" only fields, "Nillable" fields are pointers in the generated field.
func (b *{{ $builder }}) Nillable() *{{ $builder }} {
b.nillable = true
return b
}
// Comment sets the comment of the field.
func (b *{{ $builder }}) Comment(c string) *{{ $builder }} {
return b
}
// Optional indicates that this field is optional on create.
// Unlike edges, fields are required by default.
func (b *{{ $builder }}) Optional() *{{ $builder }} {
b.optional = true
return b
}
// Immutable indicates that this field cannot be updated.
func (b *{{ $builder }}) Immutable() *{{ $builder }} {
b.immutable = true
return b
}
// StructTag sets the struct tag of the field.
func (b *{{ $builder }}) StructTag(s string) *{{ $builder }} {
b.tag = s
return b
}
// Validate adds a validator for this field. Operation fails if the validation fails.
func (b *{{ $builder }}) Validate(fn func({{ $t }}) error) *{{ $builder }} {
b.validators = append(b.validators, fn)
return b
}
{{ end }}
{{ range $_, $t := $.Floats }}
{{ $builder := printf "%sBuilder" $t }}
// {{ $builder }} is the builder for float fields.
type {{ $builder }} struct {
Field
}
// Unique makes the field unique within all vertices of this type.
func (b *{{ $builder }}) Unique() *{{ $builder }} {
b.unique = true
return b
}
// Range adds a range validator for this field where the given value needs to be in the range of [i, j].
func (b *{{ $builder }}) Range(i, j {{ $t }}) *{{ $builder }} {
b.validators = append(b.validators, func(v {{ $t }}) error {
if v < i || v > j {
return errors.New("value out of range")
}
return nil
})
return b
}
// Min adds a minimum value validator for this field. Operation fails if the validator fails.
func (b *{{ $builder }}) Min(i {{ $t }}) *{{ $builder }} {
b.validators = append(b.validators, func(v {{ $t }}) error {
if v < i {
return errors.New("value out of range")
}
return nil
})
return b
}
// Max adds a maximum value validator for this field. Operation fails if the validator fails.
func (b *{{ $builder }}) Max(i {{ $t }}) *{{ $builder }} {
b.validators = append(b.validators, func(v {{ $t }}) error {
if v > i {
return errors.New("value out of range")
}
return nil
})
return b
}
// Positive adds a minimum value validator with the value of 0.000001. Operation fails if the validator fails.
func (b *{{ $builder }}) Positive() *{{ $builder }} {
return b.Min(1e-06)
}
// Negative adds a maximum value validator with the value of -0.000001. Operation fails if the validator fails.
func (b *{{ $builder }}) Negative() *{{ $builder }} {
return b.Max(-1e-06)
}
// Default sets the default value of the field.
func (b *{{ $builder }}) Default(i {{ $t }}) *{{ $builder }} {
b.value = i
return b
}
// Nillable indicates that this field is a nillable.
// Unlike "Optional" only fields, "Nillable" fields are pointers in the generated field.
func (b *{{ $builder }}) Nillable() *{{ $builder }} {
b.nillable = true
return b
}
// Comment sets the comment of the field.
func (b *{{ $builder }}) Comment(c string) *{{ $builder }} {
return b
}
// Optional indicates that this field is optional on create.
// Unlike edges, fields are required by default.
func (b *{{ $builder }}) Optional() *{{ $builder }} {
b.optional = true
return b
}
// Immutable indicates that this field cannot be updated.
func (b *{{ $builder }}) Immutable() *{{ $builder }} {
b.immutable = true
return b
}
// StructTag sets the struct tag of the field.
func (b *{{ $builder }}) StructTag(s string) *{{ $builder }} {
b.tag = s
return b
}
// Validate adds a validator for this field. Operation fails if the validation fails.
func (b *{{ $builder }}) Validate(fn func({{ $t }}) error) *{{ $builder }} {
b.validators = append(b.validators, fn)
return b
}
{{ end }}
{{ end }}

1180
schema/field/numeric.go Normal file

File diff suppressed because it is too large Load Diff