diff --git a/pkg/api/api.go b/pkg/api/api.go index 957dc0b..515e3f1 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -207,6 +207,8 @@ func HandleQuery(query string, c *gin.Context) { c.Writer.Header().Set("Content-disposition", "attachment;filename="+filename) } + result.PrepareBigints() + switch format { case "csv": c.Data(200, "text/csv", result.CSV()) diff --git a/pkg/client/result.go b/pkg/client/result.go index fcda930..3c36158 100644 --- a/pkg/client/result.go +++ b/pkg/client/result.go @@ -5,6 +5,8 @@ import ( "encoding/csv" "encoding/json" "fmt" + "reflect" + "strconv" ) type Row []interface{} @@ -14,6 +16,22 @@ type Result struct { Rows []Row `json:"rows"` } +// Due to big int number limitations in javascript, numbers should be encoded +// as strings so they could be properly loaded on the frontend. +func (res *Result) PrepareBigints() { + for i, row := range res.Rows { + for j, col := range row { + if col == nil { + continue + } + + if reflect.TypeOf(col).Kind() == reflect.Int64 { + res.Rows[i][j] = strconv.FormatInt(col.(int64), 10) + } + } + } +} + func (res *Result) Format() []map[string]interface{} { var items []map[string]interface{} diff --git a/pkg/client/result_test.go b/pkg/client/result_test.go index 7a58e67..be31183 100644 --- a/pkg/client/result_test.go +++ b/pkg/client/result_test.go @@ -7,6 +7,23 @@ import ( "github.com/stretchr/testify/assert" ) +func Test_PrepareBigints(t *testing.T) { + result := Result{ + Columns: []string{"value"}, + Rows: []Row{ + Row{int(1234)}, + Row{int64(9223372036854775807)}, + Row{int64(-9223372036854775808)}, + }, + } + + result.PrepareBigints() + + assert.Equal(t, 1234, result.Rows[0][0]) + assert.Equal(t, "9223372036854775807", result.Rows[1][0]) + assert.Equal(t, "-9223372036854775808", result.Rows[2][0]) +} + func Test_CSV(t *testing.T) { result := Result{ Columns: []string{"id", "name", "email"},