Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #3245 #3298

Merged
merged 10 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion database/gdb/gdb_func.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ var (
quoteWordReg = regexp.MustCompile(`^[a-zA-Z0-9\-_]+$`)

// structTagPriority tags for struct converting for orm field mapping.
structTagPriority = append([]string{OrmTagForStruct}, gconv.StructTagPriority...)
structTagPriority = append([]string{OrmTagForStruct}, gstructs.StructTagPriority...)
)

// WithDB injects given db object into context and returns a new context.
Expand Down
6 changes: 3 additions & 3 deletions net/ghttp/ghttp_request_param.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ import (
)

const (
parseTypeRequest = 0
parseTypeQuery = 1
parseTypeForm = 2
parseTypeRequest = iota
oldme-git marked this conversation as resolved.
Show resolved Hide resolved
parseTypeQuery
parseTypeForm
)

var (
Expand Down
5 changes: 3 additions & 2 deletions net/ghttp/ghttp_request_param_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ func (r *Request) doGetRequestStruct(pointer interface{}, mapping ...map[string]
if err = r.mergeInTagStructValue(data, pointer); err != nil {
return data, nil
}

return data, gconv.Struct(data, pointer, mapping...)
}

Expand Down Expand Up @@ -262,7 +263,7 @@ func (r *Request) mergeInTagStructValue(data map[string]interface{}, pointer int
if tagValue := field.TagIn(); tagValue != "" {
switch tagValue {
case goai.ParameterInHeader:
foundHeaderKey, foundHeaderValue := gutil.MapPossibleItemByKey(headerMap, field.Name())
foundHeaderKey, foundHeaderValue := gutil.MapPossibleItemByKey(headerMap, field.PriorityName())
if foundHeaderKey != "" {
foundKey, foundValue = gutil.MapPossibleItemByKey(data, foundHeaderKey)
if foundKey == "" {
Expand All @@ -274,7 +275,7 @@ func (r *Request) mergeInTagStructValue(data map[string]interface{}, pointer int
}
}
case goai.ParameterInCookie:
foundCookieKey, foundCookieValue := gutil.MapPossibleItemByKey(cookieMap, field.Name())
foundCookieKey, foundCookieValue := gutil.MapPossibleItemByKey(cookieMap, field.PriorityName())
if foundCookieKey != "" {
foundKey, foundValue = gutil.MapPossibleItemByKey(data, foundCookieKey)
if foundKey == "" {
Expand Down
44 changes: 44 additions & 0 deletions net/ghttp/ghttp_z_unit_issue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -524,3 +524,47 @@ func Test_Issue2457(t *testing.T) {
t.Assert(c.GetContent(ctx, "/list"), `{"code":0,"message":"","data":{"Code":100,"Data":{"Title":"title","Content":"hello"},"Msg":""}}`)
})
}

// https:/gogf/gf/issues/3245
type Issue3245Req struct {
g.Meta `path:"/hello" method:"get"`
Name string `p:"nickname" json:"name"`
XHeaderName string `p:"Header-Name" in:"header" json:"X-Header-Name"`
XHeaderAge uint8 `p:"Header-Age" in:"cookie" json:"X-Header-Age"`
}
type Issue3245Res struct {
Reply any
}

type Issue3245V1 struct{}

func (Issue3245V1) Hello(ctx context.Context, req *Issue3245Req) (res *Issue3245Res, err error) {
res = &Issue3245Res{
Reply: req,
}
return
}

func Test_Issue3245(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
s := g.Server(guid.S())
s.Use(ghttp.MiddlewareHandlerResponse)
s.Group("/", func(group *ghttp.RouterGroup) {
group.Bind(
new(Issue3245V1),
)
})
s.SetDumpRouterMap(false)
s.Start()
defer s.Shutdown()
time.Sleep(100 * time.Millisecond)

c := g.Client()
c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
c.SetHeader("Header-Name", "oldme")
c.SetCookie("Header-Age", "25")

expect := `{"code":0,"message":"","data":{"Reply":{"name":"oldme","X-Header-Name":"oldme","X-Header-Age":25}}}`
t.Assert(c.GetContent(ctx, "/hello?nickname=oldme"), expect)
})
}
9 changes: 1 addition & 8 deletions net/goai/goai_parameter_ref.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/gogf/gf/v2/internal/json"
"github.com/gogf/gf/v2/os/gstructs"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
)

// Parameters is specified by OpenAPI/Swagger 3.0 standard.
Expand All @@ -30,14 +29,8 @@ type ParameterRef struct {
func (oai *OpenApiV3) newParameterRefWithStructMethod(field gstructs.Field, path, method string) (*ParameterRef, error) {
var (
tagMap = field.TagMap()
fieldName = field.Name()
fieldName = field.PriorityName()
)
for _, tagName := range gconv.StructTagPriority {
if tagValue := field.Tag(tagName); tagValue != "" {
fieldName = tagValue
break
}
}
fieldName = gstr.Split(gstr.Trim(fieldName), ",")[0]
if fieldName == "" {
fieldName = field.Name()
Expand Down
8 changes: 1 addition & 7 deletions net/goai/goai_shema.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,7 @@ func (oai *OpenApiV3) structToSchema(object interface{}) (*Schema, error) {
if !gstr.IsLetterUpper(structField.Name()[0]) {
continue
}
var fieldName = structField.Name()
for _, tagName := range gconv.StructTagPriority {
if tagValue := structField.Tag(tagName); tagValue != "" {
fieldName = tagValue
break
}
}
var fieldName = structField.PriorityName()
fieldName = gstr.Split(gstr.Trim(fieldName), ",")[0]
if fieldName == "" {
fieldName = structField.Name()
Expand Down
6 changes: 3 additions & 3 deletions os/gstructs/gstructs.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ type FieldMapInput struct {
type RecursiveOption int

const (
RecursiveOptionNone RecursiveOption = 0 // No recursively retrieving fields as map if the field is an embedded struct.
RecursiveOptionEmbedded RecursiveOption = 1 // Recursively retrieving fields as map if the field is an embedded struct.
RecursiveOptionEmbeddedNoTag RecursiveOption = 2 // Recursively retrieving fields as map if the field is an embedded struct and the field has no tag.
RecursiveOptionNone RecursiveOption = iota // No recursively retrieving fields as map if the field is an embedded struct.
RecursiveOptionEmbedded // Recursively retrieving fields as map if the field is an embedded struct.
RecursiveOptionEmbeddedNoTag // Recursively retrieving fields as map if the field is an embedded struct and the field has no tag.
)

// Fields retrieves and returns the fields of `pointer` as slice.
Expand Down
13 changes: 13 additions & 0 deletions os/gstructs/gstructs_field.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,16 @@ func (f *Field) IsEmpty() bool {
func (f *Field) IsNil(traceSource ...bool) bool {
return empty.IsNil(f.Value, traceSource...)
}

// PriorityName returns tag name first in StructTagPriority
// Then returns Name if it doesn't have a tag name anything.
oldme-git marked this conversation as resolved.
Show resolved Hide resolved
func (f *Field) PriorityName() string {
oldme-git marked this conversation as resolved.
Show resolved Hide resolved
var name = f.Name()
for _, tagName := range StructTagPriority {
if tagValue := f.Tag(tagName); tagValue != "" {
name = tagValue
break
}
}
return name
}
7 changes: 7 additions & 0 deletions os/gstructs/gstructs_tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ import (
"github.com/gogf/gf/v2/util/gtag"
)

// StructTagPriority defines the default priority tags for Map*/Struct* functions.
// Note that, the `gconv/param` tags are used by old version of package.
// It is strongly recommended using short tag `c/p` instead in the future.
var StructTagPriority = []string{
gtag.GConv, gtag.Param, gtag.GConvShort, gtag.ParamShort, gtag.Json,
}

// ParseTag parses tag string into map.
// For example:
// ParseTag(`v:"required" p:"id" d:"1"`) => map[v:required p:id d:1].
Expand Down
20 changes: 20 additions & 0 deletions os/gstructs/gstructs_z_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,26 @@ func Test_Fields_WithEmbedded_Filter(t *testing.T) {
})
}

func Test_Fields_PriorityName(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
type User struct {
Name string `gconv:"name_gconv" c:"name_c"`
Age uint `p:"name_p" param:"age_param"`
Pass string `json:"pass_json"`
IsMen bool
}
var user *User
fields, _ := gstructs.Fields(gstructs.FieldsInput{
Pointer: user,
RecursiveOption: 0,
})
t.Assert(fields[0].PriorityName(), "name_gconv")
t.Assert(fields[1].PriorityName(), "age_param")
t.Assert(fields[2].PriorityName(), "pass_json")
t.Assert(fields[3].PriorityName(), "IsMen")
})
}

func Test_FieldMap(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
type User struct {
Expand Down
8 changes: 0 additions & 8 deletions util/gconv/gconv.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"github.com/gogf/gf/v2/internal/json"
"github.com/gogf/gf/v2/internal/reflection"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gtag"
)

var (
Expand All @@ -35,13 +34,6 @@ var (
"off": {},
"false": {},
}

// StructTagPriority defines the default priority tags for Map*/Struct* functions.
// Note that, the `gconv/param` tags are used by old version of package.
// It is strongly recommended using short tag `c/p` instead in the future.
StructTagPriority = []string{
oldme-git marked this conversation as resolved.
Show resolved Hide resolved
gtag.GConv, gtag.Param, gtag.GConvShort, gtag.ParamShort, gtag.Json,
}
)

// Byte converts `any` to byte.
Expand Down
7 changes: 4 additions & 3 deletions util/gconv/gconv_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/gogf/gf/v2/internal/empty"
"github.com/gogf/gf/v2/internal/json"
"github.com/gogf/gf/v2/internal/utils"
"github.com/gogf/gf/v2/os/gstructs"
)

type recursiveType string
Expand Down Expand Up @@ -72,7 +73,7 @@ func doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool

var (
usedOption = getUsedMapOption(option...)
newTags = StructTagPriority
newTags = gstructs.StructTagPriority
)
if usedOption.Deep {
recursive = recursiveTypeTrue
Expand All @@ -81,9 +82,9 @@ func doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool
case 0:
// No need handling.
case 1:
newTags = append(strings.Split(usedOption.Tags[0], ","), StructTagPriority...)
newTags = append(strings.Split(usedOption.Tags[0], ","), gstructs.StructTagPriority...)
default:
newTags = append(usedOption.Tags, StructTagPriority...)
newTags = append(usedOption.Tags, gstructs.StructTagPriority...)
}
// Assert the common combination of types, and finally it uses reflection.
dataMap := make(map[string]interface{})
Expand Down
4 changes: 2 additions & 2 deletions util/gconv/gconv_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,9 @@ func doStruct(params interface{}, pointer interface{}, paramKeyToAttrMap map[str
priorityTagArray []string
)
if priorityTag != "" {
priorityTagArray = append(utils.SplitAndTrim(priorityTag, ","), StructTagPriority...)
priorityTagArray = append(utils.SplitAndTrim(priorityTag, ","), gstructs.StructTagPriority...)
} else {
priorityTagArray = StructTagPriority
priorityTagArray = gstructs.StructTagPriority
}
tagToAttrNameMap, err := gstructs.TagMapName(pointerElemReflectValue, priorityTagArray)
if err != nil {
Expand Down
Loading