From ee614f9c6b1f71e537df4a00984637c38c1f3b39 Mon Sep 17 00:00:00 2001 From: John Guo Date: Wed, 23 Feb 2022 10:27:31 +0800 Subject: [PATCH 1/4] fix issue #1563 --- util/gconv/gconv_struct.go | 14 +++++++++----- util/gconv/gconv_z_unit_struct_test.go | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/util/gconv/gconv_struct.go b/util/gconv/gconv_struct.go index 628baf3c5..b24d9d711 100644 --- a/util/gconv/gconv_struct.go +++ b/util/gconv/gconv_struct.go @@ -196,7 +196,7 @@ func doStruct(params interface{}, pointer interface{}, mapping map[string]string elemFieldType reflect.StructField elemFieldValue reflect.Value elemType = pointerElemReflectValue.Type() - attrMap = make(map[string]string) + attrMap = make(map[string]string) // Attribute name to its check name which has no symbols. ) for i := 0; i < pointerElemReflectValue.NumField(); i++ { elemFieldType = elemType.Field(i) @@ -229,7 +229,7 @@ func doStruct(params interface{}, pointer interface{}, mapping map[string]string // The key of the tagMap is the attribute name of the struct, // and the value is its replaced tag name for later comparison to improve performance. var ( - tagMap = make(map[string]string) + tagMap = make(map[string]string) // Tag name to its check name which has no symbols. priorityTagArray []string ) if priorityTag != "" { @@ -241,7 +241,6 @@ func doStruct(params interface{}, pointer interface{}, mapping map[string]string if err != nil { return err } - var foundKey string for tagName, attributeName := range tagToNameMap { // If there's something else in the tag string, // it uses the first part which is split using char ','. @@ -252,8 +251,13 @@ func doStruct(params interface{}, pointer interface{}, mapping map[string]string // If tag and attribute values both exist in `paramsMap`, // it then uses the tag value overwriting the attribute value in `paramsMap`. if paramsMap[tagName] != nil { - if foundKey, _ = utils.MapPossibleItemByKey(paramsMap, attributeName); foundKey != "" { - paramsMap[foundKey] = paramsMap[tagName] + for paramsKey, _ := range paramsMap { + if paramsKey == tagName { + continue + } + if utils.EqualFoldWithoutChars(paramsKey, attributeName) { + paramsMap[paramsKey] = paramsMap[tagName] + } } } } diff --git a/util/gconv/gconv_z_unit_struct_test.go b/util/gconv/gconv_z_unit_struct_test.go index 50b4a17f2..a224b746a 100644 --- a/util/gconv/gconv_z_unit_struct_test.go +++ b/util/gconv/gconv_z_unit_struct_test.go @@ -1271,6 +1271,7 @@ func Test_Struct_Issue1563(t *testing.T) { params2 := g.Map{ "password1": "111", "PASS1": "222", + "Pass1": "333", } if err := gconv.Struct(params2, user); err == nil { t.Assert(user.Pass1, `111`) From 3db5358dcc54f0e7f0cec4af8614568fb66de1cb Mon Sep 17 00:00:00 2001 From: John Guo Date: Wed, 23 Feb 2022 10:34:38 +0800 Subject: [PATCH 2/4] fix issue #1615 --- net/ghttp/ghttp_request.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ghttp/ghttp_request.go b/net/ghttp/ghttp_request.go index cbdf12fef..a704d6b16 100644 --- a/net/ghttp/ghttp_request.go +++ b/net/ghttp/ghttp_request.go @@ -184,7 +184,7 @@ func (r *Request) IsAjaxRequest() bool { // GetClientIp returns the client ip of this request without port. // Note that this ip address might be modified by client header. func (r *Request) GetClientIp() string { - if r.clientIp == "" { + if r.clientIp != "" { return r.clientIp } realIps := r.Header.Get("X-Forwarded-For") From 8eb9fdfcd014081a936c23dbf0759f838babc0cd Mon Sep 17 00:00:00 2001 From: John Guo Date: Wed, 23 Feb 2022 12:03:21 +0800 Subject: [PATCH 3/4] improve package gbuild; version updates --- cmd/gf/internal/cmd/cmd_version.go | 8 +++---- os/gbuild/gbuild.go | 37 ++++++++++++++++++++++-------- os/gbuild/gbuild_z_unit_test.go | 18 +++++++++------ version.go | 2 +- 4 files changed, 43 insertions(+), 22 deletions(-) diff --git a/cmd/gf/internal/cmd/cmd_version.go b/cmd/gf/internal/cmd/cmd_version.go index fbaa79a74..5a44eac47 100644 --- a/cmd/gf/internal/cmd/cmd_version.go +++ b/cmd/gf/internal/cmd/cmd_version.go @@ -29,8 +29,8 @@ type cVersionOutput struct{} func (c cVersion) Index(ctx context.Context, in cVersionInput) (*cVersionOutput, error) { info := gbuild.Info() - if info["git"] == "" { - info["git"] = "none" + if info.Git == "" { + info.Git = "none" } mlog.Printf(`GoFrame CLI Tool %s, https://goframe.org`, gf.VERSION) gfVersion, err := c.getGFVersionOfCurrentProject() @@ -41,7 +41,7 @@ func (c cVersion) Index(ctx context.Context, in cVersionInput) (*cVersionOutput, } mlog.Printf(`GoFrame Version: %s`, gfVersion) mlog.Printf(`CLI Installed At: %s`, gfile.SelfPath()) - if info["gf"] == "" { + if info.GoFrame == "" { mlog.Print(`Current is a custom installed version, no installation information.`) return nil, nil } @@ -52,7 +52,7 @@ CLI Built Detail: GF Version: %s Git Commit: %s Build Time: %s -`, info["go"], info["gf"], info["git"], info["time"]))) +`, info.Golang, info.GoFrame, info.Git, info.Time))) return nil, nil } diff --git a/os/gbuild/gbuild.go b/os/gbuild/gbuild.go index 91908ab3f..d78d1906b 100644 --- a/os/gbuild/gbuild.go +++ b/os/gbuild/gbuild.go @@ -18,6 +18,22 @@ import ( "github.com/gogf/gf/v2/internal/json" ) +// BuildInfo maintains the built info of current binary. +type BuildInfo struct { + GoFrame string // Built used GoFrame version. + Golang string // Built used Golang version. + Git string // Built used git repo. commit id and datetime. + Time string // Built datetime. + Data map[string]interface{} // All custom built data key-value pairs. +} + +const ( + gfVersion = `gfVersion` + goVersion = `goVersion` + builtGit = `builtGit` + builtTime = `builtTime` +) + var ( builtInVarStr = "" // Raw variable base64 string, which is injected by go build flags. builtInVarMap = map[string]interface{}{} // Binary custom variable map decoded. @@ -30,8 +46,8 @@ func init() { if err != nil { intlog.Errorf(context.TODO(), `%+v`, err) } - builtInVarMap["gfVersion"] = gf.VERSION - builtInVarMap["goVersion"] = runtime.Version() + builtInVarMap[gfVersion] = gf.VERSION + builtInVarMap[goVersion] = runtime.Version() intlog.Printf(context.TODO(), "build variables: %+v", builtInVarMap) } else { intlog.Print(context.TODO(), "no build variables") @@ -41,12 +57,13 @@ func init() { // Info returns the basic built information of the binary as map. // Note that it should be used with gf-cli tool "gf build", // which automatically injects necessary information into the binary. -func Info() map[string]string { - return map[string]string{ - "gf": Get("gfVersion").String(), - "go": Get("goVersion").String(), - "git": Get("builtGit").String(), - "time": Get("builtTime").String(), +func Info() BuildInfo { + return BuildInfo{ + GoFrame: Get(gfVersion).String(), + Golang: Get(goVersion).String(), + Git: Get(builtGit).String(), + Time: Get(builtTime).String(), + Data: Data(), } } @@ -61,7 +78,7 @@ func Get(name string, def ...interface{}) *gvar.Var { return nil } -// Map returns the custom build-in variable map. -func Map() map[string]interface{} { +// Data returns the custom build-in variables as map. +func Data() map[string]interface{} { return builtInVarMap } diff --git a/os/gbuild/gbuild_z_unit_test.go b/os/gbuild/gbuild_z_unit_test.go index 0f8e8e89b..35d8504d1 100644 --- a/os/gbuild/gbuild_z_unit_test.go +++ b/os/gbuild/gbuild_z_unit_test.go @@ -7,18 +7,22 @@ package gbuild_test import ( + "testing" + + "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gbuild" "github.com/gogf/gf/v2/test/gtest" - "testing" + "github.com/gogf/gf/v2/util/gconv" ) func Test_Info(t *testing.T) { gtest.C(t, func(t *gtest.T) { - t.Assert(gbuild.Info(), map[string]string{ - "gf": "", - "go": "", - "git": "", - "time": "", + t.Assert(gconv.Map(gbuild.Info()), g.Map{ + "GoFrame": "", + "Golang": "", + "Git": "", + "Time": "", + "Data": g.Map{}, }) }) } @@ -34,6 +38,6 @@ func Test_Get(t *testing.T) { func Test_Map(t *testing.T) { gtest.C(t, func(t *gtest.T) { - t.Assert(gbuild.Map(), map[string]interface{}{}) + t.Assert(gbuild.Data(), map[string]interface{}{}) }) } diff --git a/version.go b/version.go index c6740c9c8..bca0c3b58 100644 --- a/version.go +++ b/version.go @@ -1,4 +1,4 @@ package gf -const VERSION = "v2.0.0-rc2" +const VERSION = "v2.0.0-rc3" const AUTHORS = "john" From e4d56e7ad9a99b9bc457b2f0ecadfc89cde134cf Mon Sep 17 00:00:00 2001 From: John Guo Date: Wed, 23 Feb 2022 16:54:15 +0800 Subject: [PATCH 4/4] improve package gjson --- encoding/gjson/gjson.go | 3 ++ encoding/gjson/gjson_api_new_load.go | 40 ++++++++----------- .../gjson/gjson_z_unit_feature_set_test.go | 8 ++++ 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/encoding/gjson/gjson.go b/encoding/gjson/gjson.go index e35a7b026..c7938ad3f 100644 --- a/encoding/gjson/gjson.go +++ b/encoding/gjson/gjson.go @@ -90,6 +90,9 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error { // Delete item from map. delete((*pointer).(map[string]interface{}), array[i]) } else { + if (*pointer).(map[string]interface{}) == nil { + *pointer = map[string]interface{}{} + } (*pointer).(map[string]interface{})[array[i]] = value } } else { diff --git a/encoding/gjson/gjson_api_new_load.go b/encoding/gjson/gjson_api_new_load.go index 367657fa5..75f8e7bef 100644 --- a/encoding/gjson/gjson_api_new_load.go +++ b/encoding/gjson/gjson_api_new_load.go @@ -67,38 +67,30 @@ func NewWithOptions(data interface{}, options Options) *Json { } } default: - var reflectInfo = utils.OriginValueAndKind(data) + var ( + pointedData interface{} + reflectInfo = utils.OriginValueAndKind(data) + ) switch reflectInfo.OriginKind { case reflect.Slice, reflect.Array: - var i interface{} = gconv.Interfaces(data) - j = &Json{ - p: &i, - c: byte(defaultSplitChar), - vc: false, - } + pointedData = gconv.Interfaces(data) + case reflect.Map: - var i interface{} = gconv.MapDeep(data, options.Tags) - j = &Json{ - p: &i, - c: byte(defaultSplitChar), - vc: false, - } + pointedData = gconv.MapDeep(data, options.Tags) + case reflect.Struct: if v, ok := data.(iVal); ok { return NewWithOptions(v.Val(), options) } - var i interface{} = gconv.MapDeep(data, options.Tags) - j = &Json{ - p: &i, - c: byte(defaultSplitChar), - vc: false, - } + pointedData = gconv.MapDeep(data, options.Tags) + default: - j = &Json{ - p: &data, - c: byte(defaultSplitChar), - vc: false, - } + pointedData = data + } + j = &Json{ + p: &pointedData, + c: byte(defaultSplitChar), + vc: false, } } j.mu = rwmutex.New(options.Safe) diff --git a/encoding/gjson/gjson_z_unit_feature_set_test.go b/encoding/gjson/gjson_z_unit_feature_set_test.go index 003682a5d..a389d0f79 100644 --- a/encoding/gjson/gjson_z_unit_feature_set_test.go +++ b/encoding/gjson/gjson_z_unit_feature_set_test.go @@ -339,3 +339,11 @@ func Test_Set_GArray(t *testing.T) { t.Assert(j.Get("arr").Array(), g.Slice{"test"}) }) } + +func Test_Set_WithEmptyStruct(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + j := gjson.New(&struct{}{}) + t.AssertNil(j.Set("aa", "123")) + t.Assert(j.MustToJsonString(), `{"aa":"123"}`) + }) +}