From 9fe353dd0bfd5fdbcf3c30a22d6cc8e5df60396a Mon Sep 17 00:00:00 2001 From: AllenX2018 Date: Wed, 19 Aug 2020 15:40:52 +0800 Subject: [PATCH] Fix issue 3886 --- pkg/orm/orm_raw.go | 36 +++++++++++++++++++++++++----------- pkg/orm/orm_test.go | 18 ++++++++++++++++++ 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/pkg/orm/orm_raw.go b/pkg/orm/orm_raw.go index 92410eb2..c2539147 100644 --- a/pkg/orm/orm_raw.go +++ b/pkg/orm/orm_raw.go @@ -383,19 +383,33 @@ func (o *rawSet) QueryRow(containers ...interface{}) error { } } } else { - for i := 0; i < ind.NumField(); i++ { - f := ind.Field(i) - fe := ind.Type().Field(i) - _, tags := parseStructTag(fe.Tag.Get(defaultStructTagName)) - var col string - if col = tags["column"]; col == "" { - col = nameStrategyMap[nameStrategy](fe.Name) - } - if v, ok := columnsMp[col]; ok { - value := reflect.ValueOf(v).Elem().Interface() - o.setFieldValue(f, value) + // define recursive function + var recursiveSetField func(rv reflect.Value) + recursiveSetField = func(rv reflect.Value) { + for i := 0; i < rv.NumField(); i++ { + f := rv.Field(i) + fe := rv.Type().Field(i) + + // check if the field is a Struct + // recursive the Struct type + if fe.Type.Kind() == reflect.Struct { + recursiveSetField(f) + } + + _, tags := parseStructTag(fe.Tag.Get(defaultStructTagName)) + var col string + if col = tags["column"]; col == "" { + col = nameStrategyMap[nameStrategy](fe.Name) + } + if v, ok := columnsMp[col]; ok { + value := reflect.ValueOf(v).Elem().Interface() + o.setFieldValue(f, value) + } } } + + // init call the recursive function + recursiveSetField(ind) } } else { diff --git a/pkg/orm/orm_test.go b/pkg/orm/orm_test.go index cbe5c9a1..40314ab4 100644 --- a/pkg/orm/orm_test.go +++ b/pkg/orm/orm_test.go @@ -1742,6 +1742,24 @@ func TestRawQueryRow(t *testing.T) { throwFail(t, AssertIs(*status, 3)) throwFail(t, AssertIs(pid, nil)) + type Embeded struct { + Email string + } + type queryRowNoModelTest struct { + Id int + EmbedField Embeded + } + + cols = []string{ + "id", "email", + } + var row queryRowNoModelTest + query = fmt.Sprintf("SELECT %s%s%s FROM %suser%s WHERE id = ?", Q, strings.Join(cols, sep), Q, Q, Q) + err = dORM.Raw(query, 4).QueryRow(&row) + throwFail(t, err) + throwFail(t, AssertIs(row.Id, 4)) + throwFail(t, AssertIs(row.EmbedField.Email, "nobody@gmail.com")) + // test for sql.Null* fields nData := &DataNull{ NullString: sql.NullString{String: "test sql.null", Valid: true},