Skip to content

Commit

Permalink
scanner: support customer type which impl sql.scanner (#71)
Browse files Browse the repository at this point in the history
  • Loading branch information
nlimpid committed Mar 21, 2020
1 parent 12de8d6 commit 01536e4
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 3 deletions.
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/DATA-DOG/go-sqlmock v1.4.0 h1:yxQ63CFIA8Sxkh0vqIofuNrsXl/LZ42TpeTLV4Nb5HM=
github.com/DATA-DOG/go-sqlmock v1.4.0/go.mod h1:3TucWNLPFOLcHhha1CPp7Kis1UG2h/AqGROPyOeZzsM=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
Expand Down
5 changes: 5 additions & 0 deletions scanner/scanner.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package scanner

import (
"database/sql"
"errors"
"reflect"
"strconv"
Expand Down Expand Up @@ -364,6 +365,10 @@ func convert(mapValue interface{}, valuei reflect.Value, wrapErr convertErrWrapp
return handleConvertTime(assertT, mvt, vit, &valuei, wrapErr)
}

if scanner, ok := valuei.Addr().Interface().(sql.Scanner); ok {
return scanner.Scan(mapValue)
}

//according to go-mysql-driver/mysql, driver.Value type can only be:
//int64 or []byte(> maxInt64)
//float32/float64
Expand Down
100 changes: 99 additions & 1 deletion scanner/scanner_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package scanner

import (
"database/sql"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -800,14 +801,111 @@ func Test_uint8_2_any(t *testing.T) {
}
}

func Test_sql_scanner(t *testing.T) {
type user struct {
Name sql.NullString `ddb:"name"`
}

var testData = []struct {
in interface{}
out sql.NullString
err error
}{
{
in: []byte("bob"),
out: sql.NullString{
String: "bob",
Valid: true,
},
err: nil,
},
{
in: nil,
out: sql.NullString{Valid: false},
err: nil,
},
{
in: 0xffff,
out: sql.NullString{
String: "65535",
Valid: true,
},
err: nil,
},
}
ass := assert.New(t)
for _, tc := range testData {
var u user
mp := map[string]interface{}{
"name": tc.in,
}
err := bind(mp, &u)
if tc.err == nil {
ass.NoError(err)
} else {
ass.Error(err)
}
ass.Equal(tc.out, u.Name)
}
}

func Test_sql_scanner_with_pointer(t *testing.T) {
type user struct {
Name *sql.NullString `ddb:"name"`
}

var testData = []struct {
in interface{}
out *sql.NullString
err error
}{
{
in: []byte("bob"),
out: &sql.NullString{
String: "bob",
Valid: true,
},
err: nil,
},
{
in: nil,
out: nil,
err: nil,
},
{
in: 0xffff,
out: &sql.NullString{
String: "65535",
Valid: true,
},
err: nil,
},
}
ass := assert.New(t)
for _, tc := range testData {
var u user
mp := map[string]interface{}{
"name": tc.in,
}
err := bind(mp, &u)
if tc.err == nil {
ass.NoError(err)
} else {
ass.Error(err)
}
ass.Equal(tc.out, u.Name)
}
}

func TestTagSetOnlyOnce(t *testing.T) {
userDefinedTagName = "a"
SetTagName("foo")
assert.Equal(t, "a", userDefinedTagName)
userDefinedTagName = ""
SetTagName("foo")
assert.Equal(t, "foo", userDefinedTagName)

// restore default tag
userDefinedTagName = DefaultTagName
}

type fakeRows struct {
Expand Down

0 comments on commit 01536e4

Please sign in to comment.