mirror of
https://github.com/syumai/workers.git
synced 2025-03-11 09:49:12 +00:00
Merge pull request #23 from syumai/d1-treat-integral-float64-as-int64
treat D1 driver row's integral float64 value as int64
This commit is contained in:
commit
efa79d96d2
@ -4,6 +4,7 @@ import (
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"io"
|
||||
"math"
|
||||
"sync"
|
||||
"syscall/js"
|
||||
|
||||
@ -50,6 +51,15 @@ func (r *rows) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// isIntegralNumber returns if given float64 value is integral value or not.
|
||||
func isIntegralNumber(f float64) bool {
|
||||
// If the value is NaN or Inf, returns the value to avoid being mistakenly treated as an integral value.
|
||||
if math.IsNaN(f) || math.IsInf(f, 0) {
|
||||
return false
|
||||
}
|
||||
return f == math.Trunc(f)
|
||||
}
|
||||
|
||||
// convertRowColumnValueToDriverValue converts row column's value in JS to Go's driver.Value.
|
||||
// row column value is `null | Number | String | ArrayBuffer`.
|
||||
// see: https://developers.cloudflare.com/d1/platform/client-api/#type-conversion
|
||||
@ -58,8 +68,12 @@ func convertRowColumnValueToAny(v js.Value) (driver.Value, error) {
|
||||
case js.TypeNull:
|
||||
return nil, nil
|
||||
case js.TypeNumber:
|
||||
// TODO: handle INTEGER type.
|
||||
return v.Float(), nil
|
||||
fv := v.Float()
|
||||
// if the value can be treated as integral value, return as int64.
|
||||
if isIntegralNumber(fv) {
|
||||
return int64(fv), nil
|
||||
}
|
||||
return fv, nil
|
||||
case js.TypeString:
|
||||
return v.String(), nil
|
||||
case js.TypeObject:
|
||||
|
44
cloudflare/d1/rows_test.go
Normal file
44
cloudflare/d1/rows_test.go
Normal file
@ -0,0 +1,44 @@
|
||||
package d1
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_isIntegralNumber(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
f float64
|
||||
want bool
|
||||
}{
|
||||
"valid integral value": {
|
||||
f: 1,
|
||||
want: true,
|
||||
},
|
||||
"invalid float value": {
|
||||
f: 1.1,
|
||||
want: false,
|
||||
},
|
||||
"invalid NaN": {
|
||||
f: math.NaN(),
|
||||
want: false,
|
||||
},
|
||||
"invalid +Inf": {
|
||||
f: math.Inf(+1),
|
||||
want: false,
|
||||
},
|
||||
"invalid -Inf": {
|
||||
f: math.Inf(-1),
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
for name, tc := range tests {
|
||||
name := name
|
||||
tc := tc
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
if got := isIntegralNumber(tc.f); got != tc.want {
|
||||
t.Errorf("isIntegralNumber() = %v, want %v", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -108,20 +108,15 @@ ORDER BY created_at DESC;
|
||||
|
||||
articles := []model.Article{}
|
||||
for rows.Next() {
|
||||
var (
|
||||
title, body string
|
||||
id, createdAt float64 // number value is always retrieved as float64.
|
||||
)
|
||||
err = rows.Scan(&id, &title, &body, &createdAt)
|
||||
var a model.Article
|
||||
err = rows.Scan(&a.ID, &a.Title, &a.Body, &a.CreatedAt)
|
||||
if err != nil {
|
||||
break
|
||||
log.Println(err)
|
||||
h.handleErr(w, http.StatusInternalServerError,
|
||||
"failed to scan article")
|
||||
return
|
||||
}
|
||||
articles = append(articles, model.Article{
|
||||
ID: uint64(id),
|
||||
Title: title,
|
||||
Body: body,
|
||||
CreatedAt: uint64(createdAt),
|
||||
})
|
||||
articles = append(articles, a)
|
||||
}
|
||||
res := model.ListArticlesResponse{
|
||||
Articles: articles,
|
||||
|
Loading…
x
Reference in New Issue
Block a user