Skip to content

Commit 83982c7

Browse files
authored
Merge pull request #177 from jiang4869/master
【FIX】Fix the issue where conversion fails when converting from sql.NullXXX types to basic types when selecting deepCopy option.
2 parents f036a42 + 4e0e2df commit 83982c7

File tree

2 files changed

+71
-1
lines changed

2 files changed

+71
-1
lines changed

copier.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ func set(to, from reflect.Value, deepCopy bool, converters map[converterPair]Typ
558558
if from.Kind() == reflect.Ptr && from.IsNil() {
559559
return true, nil
560560
}
561-
if toKind == reflect.Struct || toKind == reflect.Map || toKind == reflect.Slice {
561+
if _, ok := to.Addr().Interface().(sql.Scanner); !ok && (toKind == reflect.Struct || toKind == reflect.Map || toKind == reflect.Slice) {
562562
return false, nil
563563
}
564564
}

copier_different_type_test.go

+70
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package copier_test
22

33
import (
4+
"database/sql"
45
"testing"
6+
"time"
57

68
"github.com/jinzhu/copier"
79
)
@@ -47,6 +49,28 @@ func (t *TypeStruct4) Field1(i int) {
4749
t.field1 = i
4850
}
4951

52+
type TypeBaseStruct5 struct {
53+
A bool
54+
B byte
55+
C float64
56+
D int16
57+
E int32
58+
F int64
59+
G time.Time
60+
H string
61+
}
62+
63+
type TypeSqlNullStruct6 struct {
64+
A sql.NullBool `json:"a"`
65+
B sql.NullByte `json:"b"`
66+
C sql.NullFloat64 `json:"c"`
67+
D sql.NullInt16 `json:"d"`
68+
E sql.NullInt32 `json:"e"`
69+
F sql.NullInt64 `json:"f"`
70+
G sql.NullTime `json:"g"`
71+
H sql.NullString `json:"h"`
72+
}
73+
5074
func TestCopyDifferentFieldType(t *testing.T) {
5175
ts := &TypeStruct1{
5276
Field1: "str1",
@@ -150,3 +174,49 @@ func checkType2WithType4(t2 TypeStruct2, t4 TypeStruct4, t *testing.T, testCase
150174
t.Errorf("%v: type struct 4 and type struct 2 is not equal", testCase)
151175
}
152176
}
177+
178+
func TestCopyFromBaseToSqlNullWithOptionDeepCopy(t *testing.T) {
179+
a := TypeBaseStruct5{
180+
A: true,
181+
B: byte(2),
182+
C: 5.5,
183+
D: 1,
184+
E: 2,
185+
F: 3,
186+
G: time.Now(),
187+
H: "deep",
188+
}
189+
b := TypeSqlNullStruct6{}
190+
191+
err := copier.CopyWithOption(&b, a, copier.Option{DeepCopy: true})
192+
// 检查是否有错误
193+
if err != nil {
194+
t.Errorf("CopyStructWithOption() error = %v", err)
195+
return
196+
}
197+
// 检查 b 结构体的字段是否符合预期
198+
if !b.A.Valid || b.A.Bool != true {
199+
t.Errorf("b.A = %v, want %v", b.A, true)
200+
}
201+
if !b.B.Valid || b.B.Byte != byte(2) {
202+
t.Errorf("b.B = %v, want %v", b.B, byte(2))
203+
}
204+
if !b.C.Valid || b.C.Float64 != 5.5 {
205+
t.Errorf("b.C = %v, want %v", b.C, 5.5)
206+
}
207+
if !b.D.Valid || b.D.Int16 != 1 {
208+
t.Errorf("b.D = %v, want %v", b.D, 1)
209+
}
210+
if !b.E.Valid || b.E.Int32 != 2 {
211+
t.Errorf("b.E = %v, want %v", b.E, 2)
212+
}
213+
if !b.F.Valid || b.F.Int64 != 3 {
214+
t.Errorf("b.F = %v, want %v", b.F, 3)
215+
}
216+
if !b.G.Valid || b.G.Time != a.G {
217+
t.Errorf("b.G = %v, want %v", b.G, a.G)
218+
}
219+
if !b.H.Valid || b.H.String != "deep" {
220+
t.Errorf("b.H = %v, want %v", b.H, "deep")
221+
}
222+
}

0 commit comments

Comments
 (0)