mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
mssql: support money, smallmoney and decimal data types
This commit is contained in:
@@ -5,17 +5,19 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"time"
|
||||
|
||||
"math"
|
||||
|
||||
_ "github.com/denisenkom/go-mssqldb"
|
||||
"github.com/go-xorm/core"
|
||||
"github.com/grafana/grafana/pkg/components/null"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/tsdb"
|
||||
"math"
|
||||
)
|
||||
|
||||
type MssqlQueryEndpoint struct {
|
||||
@@ -133,6 +135,24 @@ func (e MssqlQueryEndpoint) getTypedRowData(types []*sql.ColumnType, rows *core.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// convert types not handled by denisenkom/go-mssqldb
|
||||
// unhandled types are returned as []byte
|
||||
for i := 0; i < len(types); i++ {
|
||||
if value, ok := values[i].([]byte); ok == true {
|
||||
switch types[i].DatabaseTypeName() {
|
||||
case "MONEY", "SMALLMONEY", "DECIMAL":
|
||||
if v, err := strconv.ParseFloat(string(value), 64); err == nil {
|
||||
values[i] = v
|
||||
} else {
|
||||
e.log.Debug("Rows", "Error converting numeric to float", value)
|
||||
}
|
||||
default:
|
||||
e.log.Debug("Rows", "Unknown database type", types[i].DatabaseTypeName(), "value", value)
|
||||
values[i] = string(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return values, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ func TestMSSQL(t *testing.T) {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
|
||||
fromStart := time.Date(2018, 3, 15, 13, 0, 0, 0, time.UTC)
|
||||
|
||||
Convey("Given a table with different native data types", func() {
|
||||
sql := `
|
||||
IF OBJECT_ID('dbo.[mssql_types]', 'U') IS NOT NULL
|
||||
@@ -41,14 +43,15 @@ func TestMSSQL(t *testing.T) {
|
||||
|
||||
CREATE TABLE [mssql_types] (
|
||||
c_bit bit,
|
||||
|
||||
c_tinyint tinyint,
|
||||
c_smallint smallint,
|
||||
c_int int,
|
||||
c_bigint bigint,
|
||||
|
||||
c_money money,
|
||||
c_smallmoney smallmoney,
|
||||
c_numeric numeric(10,5),
|
||||
|
||||
c_real real,
|
||||
c_decimal decimal(10,2),
|
||||
c_float float,
|
||||
@@ -113,17 +116,17 @@ func TestMSSQL(t *testing.T) {
|
||||
column := queryResult.Tables[0].Rows[0]
|
||||
|
||||
So(column[0].(bool), ShouldEqual, true)
|
||||
|
||||
So(column[1].(int64), ShouldEqual, 5)
|
||||
So(column[2].(int64), ShouldEqual, 20020)
|
||||
So(column[3].(int64), ShouldEqual, 980300)
|
||||
So(column[4].(int64), ShouldEqual, 1420070400)
|
||||
// So(column[5].(float64), ShouldEqual, 20000.15)
|
||||
// So(column[6].(float64), ShouldEqual, 2.15)
|
||||
//So(column[7].(float64), ShouldEqual, 12345.12)
|
||||
|
||||
So(column[8].(float64), ShouldEqual, 1.1100000143051147) // MSSQL dose not have precision for "real" datatype
|
||||
// fix me: MSSQL driver puts the decimal inside an array of chars. and the test fails despite the values are correct.
|
||||
//So(column[9].([]uint8), ShouldEqual, []uint8{'2', '.', '2', '2'})
|
||||
So(column[5].(float64), ShouldEqual, 20000.15)
|
||||
So(column[6].(float64), ShouldEqual, 2.15)
|
||||
So(column[7].(float64), ShouldEqual, 12345.12)
|
||||
So(column[8].(float64), ShouldEqual, 1.1100000143051147)
|
||||
So(column[9].(float64), ShouldEqual, 2.22)
|
||||
So(column[10].(float64), ShouldEqual, 3.33)
|
||||
|
||||
So(column[11].(string), ShouldEqual, "char10 ")
|
||||
|
||||
Reference in New Issue
Block a user