schema/field: support validator for Bytes fields

Fixed #1714
This commit is contained in:
Ariel Mashraki
2021-07-13 16:25:45 +03:00
committed by Ariel Mashraki
parent c8ed4e9d7a
commit 4eefbb6af9
11 changed files with 67 additions and 1 deletions

View File

@@ -251,6 +251,8 @@ var (
LinkValidator func(string) error
// DefaultIP holds the default value on creation for the "ip" field.
DefaultIP func() net.IP
// IPValidator is a validator for the "ip" field. It is called by the builders before save.
IPValidator func([]byte) error
// DefaultPair holds the default value on creation for the "pair" field.
DefaultPair func() schema.Pair
// DefaultVstring holds the default value on creation for the "vstring" field.

View File

@@ -874,6 +874,11 @@ func (ftc *FieldTypeCreate) check() error {
return &ValidationError{Name: "link", err: fmt.Errorf("ent: validator failed for field \"link\": %w", err)}
}
}
if v, ok := ftc.mutation.IP(); ok {
if err := fieldtype.IPValidator([]byte(v)); err != nil {
return &ValidationError{Name: "ip", err: fmt.Errorf("ent: validator failed for field \"ip\": %w", err)}
}
}
if _, ok := ftc.mutation.Role(); !ok {
return &ValidationError{Name: "role", err: errors.New("ent: missing required field \"role\"")}
}

View File

@@ -1358,6 +1358,11 @@ func (ftu *FieldTypeUpdate) check() error {
return &ValidationError{Name: "link", err: fmt.Errorf("ent: validator failed for field \"link\": %w", err)}
}
}
if v, ok := ftu.mutation.IP(); ok {
if err := fieldtype.IPValidator([]byte(v)); err != nil {
return &ValidationError{Name: "ip", err: fmt.Errorf("ent: validator failed for field \"ip\": %w", err)}
}
}
if v, ok := ftu.mutation.Role(); ok {
if err := fieldtype.RoleValidator(v); err != nil {
return &ValidationError{Name: "role", err: fmt.Errorf("ent: validator failed for field \"role\": %w", err)}
@@ -3687,6 +3692,11 @@ func (ftuo *FieldTypeUpdateOne) check() error {
return &ValidationError{Name: "link", err: fmt.Errorf("ent: validator failed for field \"link\": %w", err)}
}
}
if v, ok := ftuo.mutation.IP(); ok {
if err := fieldtype.IPValidator([]byte(v)); err != nil {
return &ValidationError{Name: "ip", err: fmt.Errorf("ent: validator failed for field \"ip\": %w", err)}
}
}
if v, ok := ftuo.mutation.Role(); ok {
if err := fieldtype.RoleValidator(v); err != nil {
return &ValidationError{Name: "role", err: fmt.Errorf("ent: validator failed for field \"role\": %w", err)}

View File

@@ -89,6 +89,8 @@ func init() {
fieldtypeDescIP := fieldtypeFields[42].Descriptor()
// fieldtype.DefaultIP holds the default value on creation for the ip field.
fieldtype.DefaultIP = fieldtypeDescIP.Default.(func() net.IP)
// fieldtype.IPValidator is a validator for the "ip" field. It is called by the builders before save.
fieldtype.IPValidator = fieldtypeDescIP.Validators[0].(func([]byte) error)
// fieldtypeDescPair is the schema descriptor for pair field.
fieldtypeDescPair := fieldtypeFields[55].Descriptor()
// fieldtype.DefaultPair holds the default value on creation for the pair field.

View File

@@ -194,6 +194,12 @@ func (FieldType) Fields() []ent.Field { //nolint:funlen
GoType(net.IP("127.0.0.1")).
DefaultFunc(func() net.IP {
return net.IP("127.0.0.1")
}).
Validate(func(i []byte) error {
if net.ParseIP(string(i)) == nil {
return fmt.Errorf("ent/schema: invalid ip %q", string(i))
}
return nil
}),
field.Int("null_int64").
Optional().

View File

@@ -162,6 +162,8 @@ var (
LinkValidator func(string) error
// DefaultIP holds the default value on creation for the "ip" field.
DefaultIP func() net.IP
// IPValidator is a validator for the "ip" field. It is called by the builders before save.
IPValidator func([]byte) error
// DefaultPair holds the default value on creation for the "pair" field.
DefaultPair func() schema.Pair
// DefaultVstring holds the default value on creation for the "vstring" field.

View File

@@ -875,6 +875,11 @@ func (ftc *FieldTypeCreate) check() error {
return &ValidationError{Name: "link", err: fmt.Errorf("ent: validator failed for field \"link\": %w", err)}
}
}
if v, ok := ftc.mutation.IP(); ok {
if err := fieldtype.IPValidator([]byte(v)); err != nil {
return &ValidationError{Name: "ip", err: fmt.Errorf("ent: validator failed for field \"ip\": %w", err)}
}
}
if _, ok := ftc.mutation.Role(); !ok {
return &ValidationError{Name: "role", err: errors.New("ent: missing required field \"role\"")}
}

View File

@@ -1360,6 +1360,11 @@ func (ftu *FieldTypeUpdate) check() error {
return &ValidationError{Name: "link", err: fmt.Errorf("ent: validator failed for field \"link\": %w", err)}
}
}
if v, ok := ftu.mutation.IP(); ok {
if err := fieldtype.IPValidator([]byte(v)); err != nil {
return &ValidationError{Name: "ip", err: fmt.Errorf("ent: validator failed for field \"ip\": %w", err)}
}
}
if v, ok := ftu.mutation.Role(); ok {
if err := fieldtype.RoleValidator(v); err != nil {
return &ValidationError{Name: "role", err: fmt.Errorf("ent: validator failed for field \"role\": %w", err)}
@@ -3168,6 +3173,11 @@ func (ftuo *FieldTypeUpdateOne) check() error {
return &ValidationError{Name: "link", err: fmt.Errorf("ent: validator failed for field \"link\": %w", err)}
}
}
if v, ok := ftuo.mutation.IP(); ok {
if err := fieldtype.IPValidator([]byte(v)); err != nil {
return &ValidationError{Name: "ip", err: fmt.Errorf("ent: validator failed for field \"ip\": %w", err)}
}
}
if v, ok := ftuo.mutation.Role(); ok {
if err := fieldtype.RoleValidator(v); err != nil {
return &ValidationError{Name: "role", err: fmt.Errorf("ent: validator failed for field \"role\": %w", err)}

View File

@@ -89,6 +89,8 @@ func init() {
fieldtypeDescIP := fieldtypeFields[42].Descriptor()
// fieldtype.DefaultIP holds the default value on creation for the ip field.
fieldtype.DefaultIP = fieldtypeDescIP.Default.(func() net.IP)
// fieldtype.IPValidator is a validator for the "ip" field. It is called by the builders before save.
fieldtype.IPValidator = fieldtypeDescIP.Validators[0].(func([]byte) error)
// fieldtypeDescPair is the schema descriptor for pair field.
fieldtypeDescPair := fieldtypeFields[55].Descriptor()
// fieldtype.DefaultPair holds the default value on creation for the pair field.

View File

@@ -575,6 +575,21 @@ func (b *bytesBuilder) MaxLen(i int) *bytesBuilder {
return b
}
// Validate adds a validator for this field. Operation fails if the validation fails.
//
// field.Bytes("blob").
// Validate(func(b []byte) error {
// if len(b) % 2 == 0 {
// return fmt.Errorf("ent/schema: blob length is even: %d", len(b))
// }
// return nil
// })
//
func (b *bytesBuilder) Validate(fn func([]byte) error) *bytesBuilder {
b.desc.Validators = append(b.desc.Validators, fn)
return b
}
// StorageKey sets the storage key of the field.
// In SQL dialects is the column name and Gremlin is the property.
func (b *bytesBuilder) StorageKey(key string) *bytesBuilder {

View File

@@ -187,12 +187,19 @@ func (*Pair) Scan(interface{}) error { return nil }
func (Pair) Value() (driver.Value, error) { return nil, nil }
func TestBytes(t *testing.T) {
fd := field.Bytes("active").Default([]byte("{}")).Comment("comment").Descriptor()
fd := field.Bytes("active").
Default([]byte("{}")).
Comment("comment").
Validate(func(bytes []byte) error {
return nil
}).
Descriptor()
assert.Equal(t, "active", fd.Name)
assert.Equal(t, field.TypeBytes, fd.Info.Type)
assert.NotNil(t, fd.Default)
assert.Equal(t, []byte("{}"), fd.Default)
assert.Equal(t, "comment", fd.Comment)
assert.Len(t, fd.Validators, 1)
fd = field.Bytes("ip").GoType(net.IP("127.0.0.1")).Descriptor()
assert.NoError(t, fd.Err)