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

More extensible way of doing validations #7

Closed v4n closed 8 years ago

v4n commented 8 years ago

Any thoughts or plans or making custom validations more powerful such as allowing sql queries to be executed during the validation?

For example this is how to check if a record is unique in the database (using a ozzo-validation before c5ea90):

// UniqueRecord checks that a value is unique value in the database.
func UniqueRecord(statement string, bindvars ...interface{}) *uniqueRecord {
    return &uniqueRecord{
        message:   "Value is not unique.",
        statement: statement,
        bindvars:  bindvars,
    }
}

type uniqueRecord struct {
    message   string
    statement string
    bindvars  []interface{}
}

func (v *uniqueRecord) Validate(value interface{}, context interface{}) error {
    var exists bool
    statement := "SELECT EXISTS(" + v.statement + ")"
    err := database.SQL.Get(&exists, statement, v.bindvars...)
    if err != nil || exists {
        return errors.New(v.message)
    }
    return nil
}

To validate:

Add("Email", validation.Required, is.Email,     UniqueRecord(
  "SELECT 1 FROM email WHERE email=$1", invitation.Email)
)

This is no longer possible with the updates. It would be great being able to more than data-type validations and handle SQL queries validation and more complex struct validation such as check if two struct keys are not equal.

v4n commented 8 years ago

Actually never mind, I just realized that we don't depend on context anymore to do the SQL validation.