From 5c774fd3917c8cfabadbb506702d0d1bd1799b64 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 16 Jun 2020 11:37:00 +0800 Subject: [PATCH] improve function Structs for package gconv --- database/gdb/gdb_z_mysql_model_test.go | 28 ++++++++++++ util/gconv/gconv_struct.go | 24 ++++++---- util/gconv/gconv_z_unit_struct_slice_test.go | 47 ++++++++++++++++++++ util/gconv/gconv_z_unit_struct_test.go | 1 - 4 files changed, 91 insertions(+), 9 deletions(-) diff --git a/database/gdb/gdb_z_mysql_model_test.go b/database/gdb/gdb_z_mysql_model_test.go index e1d0df458..dcaea9cb9 100644 --- a/database/gdb/gdb_z_mysql_model_test.go +++ b/database/gdb/gdb_z_mysql_model_test.go @@ -824,6 +824,34 @@ func Test_Model_Structs(t *testing.T) { }) } +func Test_Model_StructsWithJsonTag(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + type User struct { + Uid int `json:"id"` + Passport string + Password string + Name string `json:"nick_name"` + Time gtime.Time `json:"create_time"` + } + var users []User + err := db.Table(table).Order("id asc").Structs(&users) + if err != nil { + gtest.Error(err) + } + t.Assert(len(users), SIZE) + t.Assert(users[0].Uid, 1) + t.Assert(users[1].Uid, 2) + t.Assert(users[2].Uid, 3) + t.Assert(users[0].Name, "name_1") + t.Assert(users[1].Name, "name_2") + t.Assert(users[2].Name, "name_3") + t.Assert(users[0].Time.String(), "2018-10-24 10:00:00") + }) +} + func Test_Model_Scan(t *testing.T) { table := createInitTable() defer dropTable(table) diff --git a/util/gconv/gconv_struct.go b/util/gconv/gconv_struct.go index a3976c1e5..47375bd78 100644 --- a/util/gconv/gconv_struct.go +++ b/util/gconv/gconv_struct.go @@ -103,7 +103,8 @@ func Struct(params interface{}, pointer interface{}, mapping ...map[string]strin } } } - // The key of the map is the attribute name of the struct, + + // The key of the attrMap is the attribute name of the struct, // and the value is its replaced name for later comparison to improve performance. var ( attrMap = make(map[string]string) @@ -121,10 +122,17 @@ func Struct(params interface{}, pointer interface{}, mapping ...map[string]strin if len(attrMap) == 0 { return nil } + + // 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. + tagMap := make(map[string]string) + for k, v := range structs.TagMapName(pointer, structTagPriority, true) { + tagMap[v] = replaceCharReg.ReplaceAllString(k, "") + } + var ( attrName string checkName string - tagMap = structs.TagMapName(pointer, structTagPriority, true) ) for mapK, mapV := range paramsMap { attrName = "" @@ -134,22 +142,22 @@ func Struct(params interface{}, pointer interface{}, mapping ...map[string]strin // Matching the parameters to struct tag names. // The is the attribute name of the struct. - for tagK, tagV := range tagMap { - if strings.EqualFold(checkName, tagK) { - attrName = tagV + for attrKey, cmpKey := range tagMap { + if strings.EqualFold(checkName, cmpKey) { + attrName = attrKey break } } // Matching the parameters to struct attributes. - for attrK, attrV := range attrMap { + for attrKey, cmpKey := range attrMap { // Eg: // UserName eq user_name // User-Name eq username // username eq userName // etc. - if strings.EqualFold(checkName, attrV) { - attrName = attrK + if strings.EqualFold(checkName, cmpKey) { + attrName = attrKey break } } diff --git a/util/gconv/gconv_z_unit_struct_slice_test.go b/util/gconv/gconv_z_unit_struct_slice_test.go index 71a3ac54c..ade38daf0 100644 --- a/util/gconv/gconv_z_unit_struct_slice_test.go +++ b/util/gconv/gconv_z_unit_struct_slice_test.go @@ -96,3 +96,50 @@ func Test_Struct_Slice(t *testing.T) { t.Assert(user.Scores, array) }) } + +func Test_Struct_SliceWithTag(t *testing.T) { + type User struct { + Uid int `json:"id"` + NickName string `json:"name"` + } + gtest.C(t, func(t *gtest.T) { + var users []User + params := g.Slice{ + g.Map{ + "id": 1, + "name": "name1", + }, + g.Map{ + "id": 2, + "name": "name2", + }, + } + err := gconv.Structs(params, &users) + t.Assert(err, nil) + t.Assert(len(users), 2) + t.Assert(users[0].Uid, 1) + t.Assert(users[0].NickName, "name1") + t.Assert(users[1].Uid, 2) + t.Assert(users[1].NickName, "name2") + }) + gtest.C(t, func(t *gtest.T) { + var users []*User + params := g.Slice{ + g.Map{ + "id": 1, + "name": "name1", + }, + g.Map{ + "id": 2, + "name": "name2", + }, + } + err := gconv.Structs(params, &users) + t.Assert(err, nil) + t.Assert(len(users), 2) + t.Assert(users[0].Uid, 1) + t.Assert(users[0].NickName, "name1") + t.Assert(users[1].Uid, 2) + t.Assert(users[1].NickName, "name2") + }) +} diff --git a/util/gconv/gconv_z_unit_struct_test.go b/util/gconv/gconv_z_unit_struct_test.go index c79448c3c..f08360913 100644 --- a/util/gconv/gconv_z_unit_struct_test.go +++ b/util/gconv/gconv_z_unit_struct_test.go @@ -155,7 +155,6 @@ func Test_Struct_Attr_Slice1(t *testing.T) { // }) //} -// 属性为struct对象 func Test_Struct_Attr_Struct(t *testing.T) { gtest.C(t, func(t *gtest.T) { type Score struct {