From dbb28729cc7e35e802b6b3df5084799518b8f72b Mon Sep 17 00:00:00 2001 From: nlimpid Date: Mon, 20 Mar 2023 13:21:08 +0800 Subject: [PATCH] feat: support empty tag (#136) Co-authored-by: jieshuang --- scanner/scanner.go | 25 +++++++++++++------------ scanner/scanner_test.go | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/scanner/scanner.go b/scanner/scanner.go index c270617..192b8d1 100644 --- a/scanner/scanner.go +++ b/scanner/scanner.go @@ -23,7 +23,7 @@ type ByteUnmarshaler interface { UnmarshalByte(data []byte) error } -//Rows defines methods that scanner needs, which database/sql.Rows already implements +// Rows defines methods that scanner needs, which database/sql.Rows already implements type Rows interface { Close() error @@ -41,7 +41,7 @@ const ( ) var ( - userDefinedTagName string + userDefinedTagName *string //ErrTargetNotSettable means the second param of Bind is not settable ErrTargetNotSettable = errors.New("[scanner]: target is not settable! a pointer is required") //ErrNilRows means the first param can't be a nil @@ -52,15 +52,15 @@ var ( ErrEmptyResult = errors.New(`[scanner]: empty result`) ) -//SetTagName can be set only once +// SetTagName can be set only once func SetTagName(name string) { - if userDefinedTagName != "" { + if userDefinedTagName != nil { return } - userDefinedTagName = name + userDefinedTagName = &name } -//ScanErr will be returned if an underlying type couldn't be AssignableTo type of target field +// ScanErr will be returned if an underlying type couldn't be AssignableTo type of target field type ScanErr struct { structName, fieldName string from, to reflect.Type @@ -202,7 +202,7 @@ func ScanClose(rows Rows, target interface{}) error { return err } -//caller must guarantee to pass a &slice as the second param +// caller must guarantee to pass a &slice as the second param func bindSlice(arr []map[string]interface{}, target interface{}) error { targetObj := reflect.ValueOf(target) if !targetObj.Elem().CanSet() { @@ -333,11 +333,12 @@ func resolveDataFromRows(rows Rows) ([]map[string]interface{}, error) { } func lookUpTagName(typeObj reflect.StructField) (string, bool) { - var tName string - if "" != userDefinedTagName { - tName = userDefinedTagName - } else { - tName = DefaultTagName + tName := DefaultTagName + if userDefinedTagName != nil { + tName = *userDefinedTagName + } + if tName == "" { + return typeObj.Name, true } name, ok := typeObj.Tag.Lookup(tName) if !ok { diff --git a/scanner/scanner_test.go b/scanner/scanner_test.go index 0ced576..8846b6c 100644 --- a/scanner/scanner_test.go +++ b/scanner/scanner_test.go @@ -948,15 +948,37 @@ func Test_sql_scanner_with_pointer(t *testing.T) { } } +func TestBindWithEmptyTag(t *testing.T) { + emptyStr := "" + userDefinedTagName = &emptyStr + type Person struct { + Name string + Age int + } + var p Person + name := "deen" + age := 23 + var mp = map[string]interface{}{ + "Name": name, + "Age": age, + } + err := bind(mp, &p) + should := require.New(t) + should.NoError(err) + should.Equal(name, p.Name) + should.Equal(age, p.Age) +} + func TestTagSetOnlyOnce(t *testing.T) { - userDefinedTagName = "a" + a := "a" + userDefinedTagName = &a SetTagName("foo") - require.Equal(t, "a", userDefinedTagName) - userDefinedTagName = "" + require.Equal(t, "a", *userDefinedTagName) + userDefinedTagName = nil SetTagName("foo") - require.Equal(t, "foo", userDefinedTagName) + require.Equal(t, "foo", *userDefinedTagName) // restore default tag - userDefinedTagName = DefaultTagName + userDefinedTagName = nil } type fakeRows struct { @@ -1044,7 +1066,8 @@ func TestScanMock(t *testing.T) { Age int `ddb:"age"` } var boys []curdBoy - userDefinedTagName = "ddb" + defaultTag := DefaultTagName + userDefinedTagName = &defaultTag err := Scan(scannn, &boys) should.NoError(err) should.Equal("deen", boys[0].Name) @@ -1061,7 +1084,7 @@ func TestScanEmpty(t *testing.T) { Age int `ddb:"age"` } var boys []curdBoy - userDefinedTagName = "ddb" + *userDefinedTagName = "ddb" err := Scan(scannn, &boys) should.NoError(err) should.Equal(0, len(boys))