From 44819b135ecac57ec8a76d0410a02cf26920b335 Mon Sep 17 00:00:00 2001 From: John Guo Date: Mon, 18 Dec 2023 20:19:18 +0800 Subject: [PATCH] fix issue #3204 (#3212) --- contrib/drivers/mysql/mysql_issue_test.go | 25 +++++++++++++++++++++++ database/gdb/gdb_core_structure.go | 2 +- database/gdb/gdb_func.go | 18 +++++++++++----- database/gdb/gdb_model_insert.go | 2 +- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/contrib/drivers/mysql/mysql_issue_test.go b/contrib/drivers/mysql/mysql_issue_test.go index 0a8a26872..a57ba1ea1 100644 --- a/contrib/drivers/mysql/mysql_issue_test.go +++ b/contrib/drivers/mysql/mysql_issue_test.go @@ -881,3 +881,28 @@ func Test_Issue3086(t *testing.T) { t.Assert(n, 2) }) } + +// https://github.com/gogf/gf/issues/3204 +func Test_Issue3204(t *testing.T) { + table := createInitTable() + defer dropTable(table) + db.SetDebug(true) + gtest.C(t, func(t *gtest.T) { + type User struct { + g.Meta `orm:"do:true"` + Id interface{} `orm:"id,omitempty"` + Passport interface{} `orm:"passport,omitempty"` + Password interface{} `orm:"password,omitempty"` + Nickname interface{} `orm:"nickname,omitempty"` + CreateTime interface{} `orm:"create_time,omitempty"` + } + where := User{ + Id: 2, + Passport: "", + } + all, err := db.Model(table).Where(where).All() + t.AssertNil(err) + t.Assert(len(all), 1) + t.Assert(all[0]["id"], 2) + }) +} diff --git a/database/gdb/gdb_core_structure.go b/database/gdb/gdb_core_structure.go index da4980d0c..bcfa5abb1 100644 --- a/database/gdb/gdb_core_structure.go +++ b/database/gdb/gdb_core_structure.go @@ -60,7 +60,7 @@ func (c *Core) GetFieldType(ctx context.Context, fieldName, table, schema string func (c *Core) ConvertDataForRecord(ctx context.Context, value interface{}, table string) (map[string]interface{}, error) { var ( err error - data = DataToMapDeep(value) + data = MapOrStructToMapDeep(value, false) ) for fieldName, fieldValue := range data { data[fieldName], err = c.db.ConvertValueForField( diff --git a/database/gdb/gdb_func.go b/database/gdb/gdb_func.go index ec5850902..3fbf1e7de 100644 --- a/database/gdb/gdb_func.go +++ b/database/gdb/gdb_func.go @@ -213,11 +213,19 @@ func anyValueToMapBeforeToRecord(value interface{}) map[string]interface{} { return gconv.Map(value, gconv.MapOption{Tags: structTagPriority}) } -// DataToMapDeep converts `value` to map type recursively(if attribute struct is embedded). +// DaToMapDeep is deprecated, use MapOrStructToMapDeep instead. +func DaToMapDeep(value interface{}) map[string]interface{} { + return MapOrStructToMapDeep(value, false) +} + +// MapOrStructToMapDeep converts `value` to map type recursively(if attribute struct is embedded). // The parameter `value` should be type of *map/map/*struct/struct. // It supports embedded struct definition for struct. -func DataToMapDeep(value interface{}) map[string]interface{} { - m := gconv.Map(value, gconv.MapOption{Tags: structTagPriority}) +func MapOrStructToMapDeep(value interface{}, omitempty bool) map[string]interface{} { + m := gconv.Map(value, gconv.MapOption{ + Tags: structTagPriority, + OmitEmpty: omitempty, + }) for k, v := range m { switch v.(type) { case time.Time, *time.Time, gtime.Time, *gtime.Time, gjson.Json, *gjson.Json: @@ -413,7 +421,7 @@ func formatWhereHolder(ctx context.Context, db DB, in formatWhereHolderInput) (n newArgs = formatWhereInterfaces(db, gconv.Interfaces(in.Where), buffer, newArgs) case reflect.Map: - for key, value := range DataToMapDeep(in.Where) { + for key, value := range MapOrStructToMapDeep(in.Where, true) { if in.OmitNil && empty.IsNil(value) { continue } @@ -468,7 +476,7 @@ func formatWhereHolder(ctx context.Context, db DB, in formatWhereHolderInput) (n var ( reflectType = reflectInfo.OriginValue.Type() structField reflect.StructField - data = DataToMapDeep(in.Where) + data = MapOrStructToMapDeep(in.Where, true) ) // If `Prefix` is given, it checks and retrieves the table name. if in.Prefix != "" { diff --git a/database/gdb/gdb_model_insert.go b/database/gdb/gdb_model_insert.go index 343f36a5e..bc6b8aa82 100644 --- a/database/gdb/gdb_model_insert.go +++ b/database/gdb/gdb_model_insert.go @@ -268,7 +268,7 @@ func (m *Model) doInsertWithOption(ctx context.Context, insertOption InsertOptio default: // It uses gconv.Map here to simply fo the type converting from interface{} to map[string]interface{}, - // as there's another DataToMapDeep in next logic to do the deep converting. + // as there's another MapOrStructToMapDeep in next logic to do the deep converting. reflectInfo := reflection.OriginValueAndKind(newData) switch reflectInfo.OriginKind { // If it's slice type, it then converts it to List type.