diff --git a/database/gdb/gdb_model_condition.go b/database/gdb/gdb_model_condition.go index b71288647..775858ced 100644 --- a/database/gdb/gdb_model_condition.go +++ b/database/gdb/gdb_model_condition.go @@ -93,6 +93,11 @@ func (m *Model) WhereNotLike(column string, like interface{}) *Model { return m.Where(fmt.Sprintf(`%s NOT LIKE ?`, m.db.QuoteWord(column)), like) } +// WhereNot builds `xxx != x` statement. +func (m *Model) WhereNot(column string, value interface{}) *Model { + return m.Where(fmt.Sprintf(`%s != ?`, m.db.QuoteWord(column)), value) +} + // WhereNotIn builds `xxx NOT IN (x)` statement. func (m *Model) WhereNotIn(column string, in interface{}) *Model { return m.Where(fmt.Sprintf(`%s NOT IN (?)`, m.db.QuoteWord(column)), in) diff --git a/util/gvalid/gvalid_custom_rule.go b/util/gvalid/gvalid_custom_rule.go index 83fd4c2bb..85e431f58 100644 --- a/util/gvalid/gvalid_custom_rule.go +++ b/util/gvalid/gvalid_custom_rule.go @@ -6,13 +6,15 @@ package gvalid +import "context" + // RuleFunc is the custom function for data validation. // The parameter `rule` specifies the validation rule string, like "required", "between:1,100", etc. // The parameter `value` specifies the value for this rule to validate. // The parameter `message` specifies the custom error message or configured i18n message for this rule. // The parameter `params` specifies all the parameters that needs. You can ignore parameter `params` if // you do not really need it in your custom validation rule. -type RuleFunc func(rule string, value interface{}, message string, params map[string]interface{}) error +type RuleFunc func(ctx context.Context, rule string, value interface{}, message string, params map[string]interface{}) error var ( // customRuleFuncMap stores the custom rule functions. diff --git a/util/gvalid/gvalid_validator_check.go b/util/gvalid/gvalid_validator_check.go index fd1d78f20..9c01f21c2 100644 --- a/util/gvalid/gvalid_validator_check.go +++ b/util/gvalid/gvalid_validator_check.go @@ -8,6 +8,10 @@ package gvalid import ( "errors" + "strconv" + "strings" + "time" + "github.com/gogf/gf/internal/json" "github.com/gogf/gf/net/gipv4" "github.com/gogf/gf/net/gipv6" @@ -15,9 +19,6 @@ import ( "github.com/gogf/gf/text/gregex" "github.com/gogf/gf/util/gconv" "github.com/gogf/gf/util/gutil" - "strconv" - "strings" - "time" ) type apiTime interface { @@ -103,7 +104,7 @@ func (v *Validator) doCheckValue(key string, value interface{}, rules string, me if len(paramMap) > 0 && paramMap[0] != nil { dataMap = gconv.Map(paramMap[0]) } - if err := f(ruleItems[index], value, message, dataMap); err != nil { + if err := f(v.ctx, ruleItems[index], value, message, dataMap); err != nil { match = false errorMsgArray[ruleKey] = err.Error() } else { diff --git a/util/gvalid/gvalid_z_example_test.go b/util/gvalid/gvalid_z_example_test.go index d52175aca..423957391 100644 --- a/util/gvalid/gvalid_z_example_test.go +++ b/util/gvalid/gvalid_z_example_test.go @@ -10,12 +10,13 @@ import ( "context" "errors" "fmt" + "math" + "reflect" + "github.com/gogf/gf/container/gvar" "github.com/gogf/gf/frame/g" "github.com/gogf/gf/util/gconv" "github.com/gogf/gf/util/gvalid" - "math" - "reflect" ) func ExampleCheckMap() { @@ -115,7 +116,7 @@ func ExampleCheckStruct3() { func ExampleRegisterRule() { rule := "unique-name" - gvalid.RegisterRule(rule, func(rule string, value interface{}, message string, params map[string]interface{}) error { + gvalid.RegisterRule(rule, func(ctx context.Context, rule string, value interface{}, message string, params map[string]interface{}) error { var ( id = gconv.Int(params["Id"]) name = gconv.String(value) @@ -147,7 +148,7 @@ func ExampleRegisterRule() { func ExampleRegisterRule_OverwriteRequired() { rule := "required" - gvalid.RegisterRule(rule, func(rule string, value interface{}, message string, params map[string]interface{}) error { + gvalid.RegisterRule(rule, func(ctx context.Context, rule string, value interface{}, message string, params map[string]interface{}) error { reflectValue := reflect.ValueOf(value) if reflectValue.Kind() == reflect.Ptr { reflectValue = reflectValue.Elem() @@ -190,3 +191,78 @@ func ExampleRegisterRule_OverwriteRequired() { // // } + +func ExampleValidator_Rules() { + data := g.Map{ + "password": "123", + } + err := g.Validator().Data(data).Rules("required-with:password").Messages("请输入确认密码").CheckValue("") + fmt.Println(err.String()) + + // Output: + // 请输入确认密码 +} + +func ExampleValidator_CheckValue() { + err := g.Validator().Rules("min:18").Messages("未成年人不允许注册哟").CheckValue(16) + fmt.Println(err.String()) + + // Output: + // 未成年人不允许注册哟 +} + +func ExampleValidator_CheckMap() { + params := map[string]interface{}{ + "passport": "", + "password": "123456", + "password2": "1234567", + } + rules := map[string]string{ + "passport": "required|length:6,16", + "password": "required|length:6,16|same:password2", + "password2": "required|length:6,16", + } + messages := map[string]interface{}{ + "passport": "账号不能为空|账号长度应当在:min到:max之间", + "password": map[string]string{ + "required": "密码不能为空", + "same": "两次密码输入不相等", + }, + } + err := g.Validator().Messages(messages).Rules(rules).CheckMap(params) + if err != nil { + g.Dump(err.Maps()) + } + + // May Output: + //{ + // "passport": { + // "length": "账号长度应当在6到16之间", + // "required": "账号不能为空" + //}, + // "password": { + // "same": "两次密码输入不相等" + //} + //} +} + +func ExampleValidator_CheckStruct() { + type User struct { + Name string `v:"required#请输入用户姓名"` + Type int `v:"required#请选择用户类型"` + } + data := g.Map{ + "name": "john", + } + user := User{} + if err := gconv.Scan(data, &user); err != nil { + panic(err) + } + err := g.Validator().Data(data).CheckStruct(user) + if err != nil { + fmt.Println(err.Items()) + } + + // Output: + // [map[Type:map[required:请选择用户类型]]] +} diff --git a/util/gvalid/gvalid_z_unit_custom_rule_test.go b/util/gvalid/gvalid_z_unit_custom_rule_test.go index 9fd7caf62..c9493c861 100644 --- a/util/gvalid/gvalid_z_unit_custom_rule_test.go +++ b/util/gvalid/gvalid_z_unit_custom_rule_test.go @@ -9,9 +9,10 @@ package gvalid_test import ( "context" "errors" + "testing" + "github.com/gogf/gf/frame/g" "github.com/gogf/gf/util/gconv" - "testing" "github.com/gogf/gf/test/gtest" "github.com/gogf/gf/util/gvalid" @@ -19,7 +20,7 @@ import ( func Test_CustomRule1(t *testing.T) { rule := "custom" - err := gvalid.RegisterRule(rule, func(rule string, value interface{}, message string, params map[string]interface{}) error { + err := gvalid.RegisterRule(rule, func(ctx context.Context, rule string, value interface{}, message string, params map[string]interface{}) error { pass := gconv.String(value) if len(pass) != 6 { return errors.New(message) @@ -66,7 +67,7 @@ func Test_CustomRule1(t *testing.T) { func Test_CustomRule2(t *testing.T) { rule := "required-map" - err := gvalid.RegisterRule(rule, func(rule string, value interface{}, message string, params map[string]interface{}) error { + err := gvalid.RegisterRule(rule, func(ctx context.Context, rule string, value interface{}, message string, params map[string]interface{}) error { m := gconv.Map(value) if len(m) == 0 { return errors.New(message) @@ -110,7 +111,7 @@ func Test_CustomRule2(t *testing.T) { func Test_CustomRule_AllowEmpty(t *testing.T) { rule := "allow-empty-str" - err := gvalid.RegisterRule(rule, func(rule string, value interface{}, message string, params map[string]interface{}) error { + err := gvalid.RegisterRule(rule, func(ctx context.Context, rule string, value interface{}, message string, params map[string]interface{}) error { s := gconv.String(value) if len(s) == 0 || s == "gf" { return nil