Просмотр исходного кода

sql datasource: extract common logic for converting value column to float

Marcus Efraimsson 7 лет назад
Родитель
Сommit
76bd2aea44
2 измененных файлов с 207 добавлено и 3 удалено
  1. 109 0
      pkg/tsdb/sql_engine.go
  2. 98 3
      pkg/tsdb/sql_engine_test.go

+ 109 - 0
pkg/tsdb/sql_engine.go

@@ -2,9 +2,12 @@ package tsdb
 
 import (
 	"context"
+	"fmt"
 	"sync"
 	"time"
 
+	"github.com/grafana/grafana/pkg/components/null"
+
 	"github.com/go-xorm/core"
 	"github.com/go-xorm/xorm"
 	"github.com/grafana/grafana/pkg/components/simplejson"
@@ -185,3 +188,109 @@ func ConvertSqlTimeColumnToEpochMs(values RowValues, timeIndex int) {
 		}
 	}
 }
+
+// ConvertSqlValueColumnToFloat converts timeseries value column to float.
+func ConvertSqlValueColumnToFloat(columnName string, columnValue interface{}) (null.Float, error) {
+	var value null.Float
+
+	switch typedValue := columnValue.(type) {
+	case int:
+		value = null.FloatFrom(float64(typedValue))
+	case *int:
+		if typedValue == nil {
+			value.Valid = false
+		} else {
+			value = null.FloatFrom(float64(*typedValue))
+		}
+	case int64:
+		value = null.FloatFrom(float64(typedValue))
+	case *int64:
+		if typedValue == nil {
+			value.Valid = false
+		} else {
+			value = null.FloatFrom(float64(*typedValue))
+		}
+	case int32:
+		value = null.FloatFrom(float64(typedValue))
+	case *int32:
+		if typedValue == nil {
+			value.Valid = false
+		} else {
+			value = null.FloatFrom(float64(*typedValue))
+		}
+	case int16:
+		value = null.FloatFrom(float64(typedValue))
+	case *int16:
+		if typedValue == nil {
+			value.Valid = false
+		} else {
+			value = null.FloatFrom(float64(*typedValue))
+		}
+	case int8:
+		value = null.FloatFrom(float64(typedValue))
+	case *int8:
+		if typedValue == nil {
+			value.Valid = false
+		} else {
+			value = null.FloatFrom(float64(*typedValue))
+		}
+	case uint:
+		value = null.FloatFrom(float64(typedValue))
+	case *uint:
+		if typedValue == nil {
+			value.Valid = false
+		} else {
+			value = null.FloatFrom(float64(*typedValue))
+		}
+	case uint64:
+		value = null.FloatFrom(float64(typedValue))
+	case *uint64:
+		if typedValue == nil {
+			value.Valid = false
+		} else {
+			value = null.FloatFrom(float64(*typedValue))
+		}
+	case uint32:
+		value = null.FloatFrom(float64(typedValue))
+	case *uint32:
+		if typedValue == nil {
+			value.Valid = false
+		} else {
+			value = null.FloatFrom(float64(*typedValue))
+		}
+	case uint16:
+		value = null.FloatFrom(float64(typedValue))
+	case *uint16:
+		if typedValue == nil {
+			value.Valid = false
+		} else {
+			value = null.FloatFrom(float64(*typedValue))
+		}
+	case uint8:
+		value = null.FloatFrom(float64(typedValue))
+	case *uint8:
+		if typedValue == nil {
+			value.Valid = false
+		} else {
+			value = null.FloatFrom(float64(*typedValue))
+		}
+	case float64:
+		value = null.FloatFrom(typedValue)
+	case *float64:
+		value = null.FloatFromPtr(typedValue)
+	case float32:
+		value = null.FloatFrom(float64(typedValue))
+	case *float32:
+		if typedValue == nil {
+			value.Valid = false
+		} else {
+			value = null.FloatFrom(float64(*typedValue))
+		}
+	case nil:
+		value.Valid = false
+	default:
+		return null.NewFloat(0, false), fmt.Errorf("Value column must have numeric datatype, column: %s type: %T value: %v", columnName, typedValue, typedValue)
+	}
+
+	return value, nil
+}

+ 98 - 3
pkg/tsdb/sql_engine_test.go

@@ -1,10 +1,11 @@
 package tsdb
 
 import (
-	"fmt"
 	"testing"
 	"time"
 
+	"github.com/grafana/grafana/pkg/components/null"
+
 	. "github.com/smartystreets/goconvey/convey"
 )
 
@@ -156,8 +157,6 @@ func TestSqlEngine(t *testing.T) {
 				So(fixtures[1].(float64), ShouldEqual, tMilliseconds)
 				So(fixtures[2].(float64), ShouldEqual, tMilliseconds)
 				So(fixtures[3].(float64), ShouldEqual, tMilliseconds)
-				fmt.Println(fixtures[4].(float64))
-				fmt.Println(tMilliseconds)
 				So(fixtures[4].(float64), ShouldEqual, tMilliseconds)
 				So(fixtures[5].(float64), ShouldEqual, tMilliseconds)
 				So(fixtures[6], ShouldBeNil)
@@ -183,5 +182,101 @@ func TestSqlEngine(t *testing.T) {
 				So(fixtures[2], ShouldBeNil)
 			})
 		})
+
+		Convey("Given row with value columns", func() {
+			intValue := 1
+			int64Value := int64(1)
+			int32Value := int32(1)
+			int16Value := int16(1)
+			int8Value := int8(1)
+			float64Value := float64(1)
+			float32Value := float32(1)
+			uintValue := uint(1)
+			uint64Value := uint64(1)
+			uint32Value := uint32(1)
+			uint16Value := uint16(1)
+			uint8Value := uint8(1)
+
+			fixtures := make([]interface{}, 24)
+			fixtures[0] = intValue
+			fixtures[1] = &intValue
+			fixtures[2] = int64Value
+			fixtures[3] = &int64Value
+			fixtures[4] = int32Value
+			fixtures[5] = &int32Value
+			fixtures[6] = int16Value
+			fixtures[7] = &int16Value
+			fixtures[8] = int8Value
+			fixtures[9] = &int8Value
+			fixtures[10] = float64Value
+			fixtures[11] = &float64Value
+			fixtures[12] = float32Value
+			fixtures[13] = &float32Value
+			fixtures[14] = uintValue
+			fixtures[15] = &uintValue
+			fixtures[16] = uint64Value
+			fixtures[17] = &uint64Value
+			fixtures[18] = uint32Value
+			fixtures[19] = &uint32Value
+			fixtures[20] = uint16Value
+			fixtures[21] = &uint16Value
+			fixtures[22] = uint8Value
+			fixtures[23] = &uint8Value
+
+			var intNilPointer *int
+			var int64NilPointer *int64
+			var int32NilPointer *int32
+			var int16NilPointer *int16
+			var int8NilPointer *int8
+			var float64NilPointer *float64
+			var float32NilPointer *float32
+			var uintNilPointer *uint
+			var uint64NilPointer *uint64
+			var uint32NilPointer *uint32
+			var uint16NilPointer *uint16
+			var uint8NilPointer *uint8
+
+			nilPointerFixtures := make([]interface{}, 12)
+			nilPointerFixtures[0] = intNilPointer
+			nilPointerFixtures[1] = int64NilPointer
+			nilPointerFixtures[2] = int32NilPointer
+			nilPointerFixtures[3] = int16NilPointer
+			nilPointerFixtures[4] = int8NilPointer
+			nilPointerFixtures[5] = float64NilPointer
+			nilPointerFixtures[6] = float32NilPointer
+			nilPointerFixtures[7] = uintNilPointer
+			nilPointerFixtures[8] = uint64NilPointer
+			nilPointerFixtures[9] = uint32NilPointer
+			nilPointerFixtures[10] = uint16NilPointer
+			nilPointerFixtures[11] = uint8NilPointer
+
+			Convey("When converting values to float should return expected value", func() {
+				for _, f := range fixtures {
+					value, _ := ConvertSqlValueColumnToFloat("col", f)
+
+					if !value.Valid {
+						t.Fatalf("Failed to convert %T value, expected a valid float value", f)
+					}
+
+					if value.Float64 != null.FloatFrom(1).Float64 {
+						t.Fatalf("Failed to convert %T value, expected a float value of 1.000, but got %v", f, value)
+					}
+				}
+			})
+
+			Convey("When converting nil pointer values to float should return expected value", func() {
+				for _, f := range nilPointerFixtures {
+					value, err := ConvertSqlValueColumnToFloat("col", f)
+
+					if err != nil {
+						t.Fatalf("Failed to convert %T value, expected a non nil error, but got %v", f, err)
+					}
+
+					if value.Valid {
+						t.Fatalf("Failed to convert %T value, expected an invalid float value", f)
+					}
+				}
+			})
+		})
 	})
 }