Skip to content

Commit dd603cb

Browse files
authored
Support scanning uint64 (shopspring#364)
1 parent 80ec940 commit dd603cb

File tree

2 files changed

+31
-73
lines changed

2 files changed

+31
-73
lines changed

decimal.go

+5
Original file line numberDiff line numberDiff line change
@@ -1847,6 +1847,11 @@ func (d *Decimal) Scan(value interface{}) error {
18471847
*d = New(v, 0)
18481848
return nil
18491849

1850+
case uint64:
1851+
// while clickhouse may send 0 in db as uint64
1852+
*d = NewFromUint64(v)
1853+
return nil
1854+
18501855
default:
18511856
// default is trying to interpret value stored as string
18521857
str, err := unquoteIfQuoted(v)

decimal_test.go

+26-73
Original file line numberDiff line numberDiff line change
@@ -2416,104 +2416,57 @@ func TestDecimal_Max(t *testing.T) {
24162416
}
24172417
}
24182418

2419-
func TestDecimal_Scan(t *testing.T) {
2420-
// test the Scan method that implements the
2421-
// sql.Scanner interface
2422-
// check for the for different type of values
2423-
// that are possible to be received from the database
2424-
// drivers
2419+
func scanHelper(t *testing.T, dbval interface{}, expected Decimal) {
2420+
t.Helper()
24252421

2426-
// in normal operations the db driver (sqlite at least)
2427-
// will return an int64 if you specified a numeric format
24282422
a := Decimal{}
2429-
dbvalue := 54.33
2430-
expected := NewFromFloat(dbvalue)
2431-
2432-
err := a.Scan(dbvalue)
2433-
if err != nil {
2423+
if err := a.Scan(dbval); err != nil {
24342424
// Scan failed... no need to test result value
2435-
t.Errorf("a.Scan(54.33) failed with message: %s", err)
2436-
2437-
} else {
2425+
t.Errorf("a.Scan(%v) failed with message: %s", dbval, err)
2426+
} else if !a.Equal(expected) {
24382427
// Scan succeeded... test resulting values
2439-
if !a.Equal(expected) {
2440-
t.Errorf("%s does not equal to %s", a, expected)
2441-
}
2428+
t.Errorf("%s does not equal to %s", a, expected)
24422429
}
2430+
}
2431+
2432+
func TestDecimal_Scan(t *testing.T) {
2433+
// test the Scan method that implements the sql.Scanner interface
2434+
// check different types received from various database drivers
2435+
2436+
dbvalue := 54.33
2437+
expected := NewFromFloat(dbvalue)
2438+
scanHelper(t, dbvalue, expected)
24432439

24442440
// apparently MySQL 5.7.16 and returns these as float32 so we need
24452441
// to handle these as well
24462442
dbvalueFloat32 := float32(54.33)
24472443
expected = NewFromFloat(float64(dbvalueFloat32))
2448-
2449-
err = a.Scan(dbvalueFloat32)
2450-
if err != nil {
2451-
// Scan failed... no need to test result value
2452-
t.Errorf("a.Scan(54.33) failed with message: %s", err)
2453-
2454-
} else {
2455-
// Scan succeeded... test resulting values
2456-
if !a.Equal(expected) {
2457-
t.Errorf("%s does not equal to %s", a, expected)
2458-
}
2459-
}
2444+
scanHelper(t, dbvalueFloat32, expected)
24602445

24612446
// at least SQLite returns an int64 when 0 is stored in the db
24622447
// and you specified a numeric format on the schema
24632448
dbvalueInt := int64(0)
24642449
expected = New(dbvalueInt, 0)
2450+
scanHelper(t, dbvalueInt, expected)
24652451

2466-
err = a.Scan(dbvalueInt)
2467-
if err != nil {
2468-
// Scan failed... no need to test result value
2469-
t.Errorf("a.Scan(0) failed with message: %s", err)
2470-
2471-
} else {
2472-
// Scan succeeded... test resulting values
2473-
if !a.Equal(expected) {
2474-
t.Errorf("%s does not equal to %s", a, expected)
2475-
}
2476-
}
2452+
// also test uint64
2453+
dbvalueUint64 := uint64(2)
2454+
expected = New(2, 0)
2455+
scanHelper(t, dbvalueUint64, expected)
24772456

24782457
// in case you specified a varchar in your SQL schema,
2479-
// the database driver will return byte slice []byte
2458+
// the database driver may return either []byte or string
24802459
valueStr := "535.666"
24812460
dbvalueStr := []byte(valueStr)
2482-
expected, err = NewFromString(valueStr)
2483-
if err != nil {
2484-
t.Fatal(err)
2485-
}
2486-
2487-
err = a.Scan(dbvalueStr)
2488-
if err != nil {
2489-
// Scan failed... no need to test result value
2490-
t.Errorf("a.Scan('535.666') failed with message: %s", err)
2491-
2492-
} else {
2493-
// Scan succeeded... test resulting values
2494-
if !a.Equal(expected) {
2495-
t.Errorf("%s does not equal to %s", a, expected)
2496-
}
2497-
}
2498-
2499-
// lib/pq can also return strings
2500-
expected, err = NewFromString(valueStr)
2461+
expected, err := NewFromString(valueStr)
25012462
if err != nil {
25022463
t.Fatal(err)
25032464
}
2504-
2505-
err = a.Scan(valueStr)
2506-
if err != nil {
2507-
// Scan failed... no need to test result value
2508-
t.Errorf("a.Scan('535.666') failed with message: %s", err)
2509-
} else {
2510-
// Scan succeeded... test resulting values
2511-
if !a.Equal(expected) {
2512-
t.Errorf("%s does not equal to %s", a, expected)
2513-
}
2514-
}
2465+
scanHelper(t, dbvalueStr, expected)
2466+
scanHelper(t, valueStr, expected)
25152467

25162468
type foo struct{}
2469+
a := Decimal{}
25172470
err = a.Scan(foo{})
25182471
if err == nil {
25192472
t.Errorf("a.Scan(Foo{}) should have thrown an error but did not")

0 commit comments

Comments
 (0)