go-ozzo / ozzo-validation

An idiomatic Go (golang) validation package. Supports configurable and extensible validation rules (validators) using normal language constructs instead of error-prone struct tags.
MIT License
3.73k stars 224 forks source link

bug about type alias #174

Open ghost opened 2 years ago

ghost commented 2 years ago

if I set a type alias of basic type,like []string ,then, I neet to add two function,such as ( value and scan ,mysql json need this), the bug is appened. the entire code under:

package main

import (
    "database/sql/driver"
    "encoding/json"
    "fmt"

    validation "github.com/go-ozzo/ozzo-validation"
)

type Tags []string

// mysql 8.0 json need value and scan function, so I need type alias
type Courses struct {
    Tag Tags `gorm:"type:json;comment:体系名是json格式" json:"tag"`
}

// !!!!!! IF YOU REMOVE THIS FUNCTION, IT IS VALIDETED !!!!!
// !!!!!! IF YOU ADD PONITER IN P, IT IS VALIDETED  !!!!
func (p Tags) Value() (driver.Value, error) {
    b, err := json.Marshal(p)
    return b, err
}

func (p *Tags) Scan(input any) error {
    return json.Unmarshal(input.([]byte), p)
}

func main() {

    var courseDto Courses
    courseDto.Tag = Tags{"student", "engineer"}
    err := validation.ValidateStruct(&courseDto,
        validation.Field(&courseDto.Tag, validation.Required, validation.Length(1, 3)),
    )
    fmt.Println(err)
}

Something strange is coming in function value !!! If p without pointer can't pass validate!

func (p Tags) Value() (driver.Value, error) {
    //b, err := json.Marshal(p)
    return nil, nil
}

But, if add pointer, it pass!

bokunodev commented 1 year ago

its because of how Value method is implemented. it return []byte from json.Unmarshal. which is obviously would be longger than 3 or shorter than 1

the solution would be to have separate type for request validation and dto.

bokunodev commented 1 year ago

solution: use is package as mentioned in the credit. asaskevich/govalidator does not check for sql valuer.