feat(sqlx): add field tag (-) skip logic in unwrapFields (#5010)

Co-authored-by: wukun30 <wukun30@meituan.com>
This commit is contained in:
wiki
2025-07-18 19:58:38 +08:00
committed by GitHub
parent f11b78ced9
commit cc79e3d842
2 changed files with 90 additions and 0 deletions

View File

@@ -279,6 +279,11 @@ func unwrapFields(v reflect.Value) []reflect.Value {
if child.Kind() == reflect.Struct && childType.Anonymous {
fields = append(fields, unwrapFields(child)...)
} else {
key := parseTagName(childType)
if key == "-" {
continue
}
fields = append(fields, child)
}
}

View File

@@ -370,6 +370,39 @@ func TestUnmarshalRowStructWithTags(t *testing.T) {
})
}
func TestUnmarshalRowStructWithTagsIgnoreFields(t *testing.T) {
dbtest.RunTest(t, func(db *sql.DB, mock sqlmock.Sqlmock) {
value := new(struct {
Age int `db:"age"`
Name string
Ignore bool
})
rs := sqlmock.NewRows([]string{"name", "age"}).FromCSVString("liao,5")
mock.ExpectQuery("select (.+) from users where user=?").WithArgs("anyone").WillReturnRows(rs)
assert.ErrorIs(t, query(context.Background(), db, func(rows *sql.Rows) error {
return unmarshalRow(value, rows, true)
}, "select name, age from users where user=?", "anyone"), ErrNotMatchDestination)
})
dbtest.RunTest(t, func(db *sql.DB, mock sqlmock.Sqlmock) {
value := new(struct {
Age int `db:"age"`
Name string
Ignore bool `db:"-"`
})
rs := sqlmock.NewRows([]string{"name", "age"}).FromCSVString("liao,5")
mock.ExpectQuery("select (.+) from users where user=?").WithArgs("anyone").WillReturnRows(rs)
assert.Nil(t, query(context.Background(), db, func(rows *sql.Rows) error {
return unmarshalRow(value, rows, true)
}, "select name, age from users where user=?", "anyone"))
assert.Equal(t, 5, value.Age)
})
}
func TestUnmarshalRowStructWithTagsWrongColumns(t *testing.T) {
value := new(struct {
Age *int `db:"age"`
@@ -999,6 +1032,58 @@ func TestUnmarshalRowsStructWithTags(t *testing.T) {
})
}
func TestUnmarshalRowsStructWithTagsIgnoreFields(t *testing.T) {
expect := []struct {
Name string
Age int64
Ignore bool
}{
{
Name: "first",
Age: 2,
Ignore: false,
},
{
Name: "second",
Age: 3,
Ignore: false,
},
}
dbtest.RunTest(t, func(db *sql.DB, mock sqlmock.Sqlmock) {
var value []struct {
Age int64 `db:"age"`
Name string `db:"name"`
Ignore bool
}
rs := sqlmock.NewRows([]string{"name", "age"}).FromCSVString("first,2\nsecond,3")
mock.ExpectQuery("select (.+) from users where user=?").WithArgs("anyone").WillReturnRows(rs)
assert.ErrorIs(t, query(context.Background(), db, func(rows *sql.Rows) error {
return unmarshalRows(&value, rows, true)
}, "select name, age from users where user=?", "anyone"), ErrNotMatchDestination)
})
dbtest.RunTest(t, func(db *sql.DB, mock sqlmock.Sqlmock) {
var value []struct {
Age int64 `db:"age"`
Name string `db:"name"`
Ignore bool `db:"-"`
}
rs := sqlmock.NewRows([]string{"name", "age"}).FromCSVString("first,2\nsecond,3")
mock.ExpectQuery("select (.+) from users where user=?").WithArgs("anyone").WillReturnRows(rs)
assert.Nil(t, query(context.Background(), db, func(rows *sql.Rows) error {
return unmarshalRows(&value, rows, true)
}, "select name, age from users where user=?", "anyone"))
for i, each := range expect {
assert.Equal(t, each.Name, value[i].Name)
assert.Equal(t, each.Age, value[i].Age)
}
})
}
func TestUnmarshalRowsStructAndEmbeddedAnonymousStructWithTags(t *testing.T) {
type Embed struct {
Value int64 `db:"value"`