Commit c9f55683 by Marcus Efraimsson

Merge branch 'master' into docs-5.1

parents 92ac1fbb 645658d7
......@@ -15,6 +15,7 @@
* **Alerting**: Add support for retries on alert queries [#5855](https://github.com/grafana/grafana/issues/5855), thx [@Thib17](https://github.com/Thib17)
* **Table**: Table plugin value mappings [#7119](https://github.com/grafana/grafana/issues/7119), thx [infernix](https://github.com/infernix)
* **IE11**: IE 11 compatibility [#11165](https://github.com/grafana/grafana/issues/11165)
* **Scrolling**: Better scrolling experience [#11053](https://github.com/grafana/grafana/issues/11053), [#11252](https://github.com/grafana/grafana/issues/11252), [#10836](https://github.com/grafana/grafana/issues/10836), [#11185](https://github.com/grafana/grafana/issues/11185), [#11168](https://github.com/grafana/grafana/issues/11168)
### Minor
* **OpsGenie**: Add triggered alerts as description [#11046](https://github.com/grafana/grafana/pull/11046), thx [@llamashoes](https://github.com/llamashoes)
......@@ -32,6 +33,21 @@
* **Annotations (native)**: Change default limit from 10 to 100 when querying api [#11569](https://github.com/grafana/grafana/issues/11569), thx [@flopp999](https://github.com/flopp999)
* **MySQL/Postgres/MSSQL**: PostgreSQL datasource generates invalid query with dates before 1970 [#11530](https://github.com/grafana/grafana/issues/11530) thx [@ryantxu](https://github.com/ryantxu)
* **Kiosk**: Adds url parameter for starting a dashboard in inactive mode [#11228](https://github.com/grafana/grafana/issues/11228), thx [@towolf](https://github.com/towolf)
* **Dashboard**: Enable closing timepicker using escape key [#11332](https://github.com/grafana/grafana/issues/11332)
* **Datasources**: Rename direct access mode in the data source settings [#11391](https://github.com/grafana/grafana/issues/11391)
* **Search**: Display dashboards in folder indented [#11073](https://github.com/grafana/grafana/issues/11073)
* **Units**: Use B/s instead Bps for Bytes per second [#9342](https://github.com/grafana/grafana/pull/9342), thx [@mayli](https://github.com/mayli)
* **Units**: Radiation units [#11001](https://github.com/grafana/grafana/issues/11001), thx [@victorclaessen](https://github.com/victorclaessen)
* **Units**: Timeticks unit [#11183](https://github.com/grafana/grafana/pull/11183), thx [@jtyr](https://github.com/jtyr)
* **Units**: Concentration units and "Normal cubic metre" [#11211](https://github.com/grafana/grafana/issues/11211), thx [@flopp999](https://github.com/flopp999)
* **Units**: New currency - Czech koruna [#11384](https://github.com/grafana/grafana/pull/11384), thx [@Rohlik](https://github.com/Rohlik)
* **Avatar**: Fix DISABLE_GRAVATAR option [#11095](https://github.com/grafana/grafana/issues/11095)
* **Heatmap**: Disable log scale when using time time series buckets [#10792](https://github.com/grafana/grafana/issues/10792)
* **Provisioning**: Remove `id` from json when provisioning dashboards, [#11138](https://github.com/grafana/grafana/issues/11138)
* **Prometheus**: tooltip for legend format not showing properly [#11516](https://github.com/grafana/grafana/issues/11516), thx [@svenklemm](https://github.com/svenklemm)
### Tech
* Migrated JavaScript files to TypeScript
# 5.0.4 (2018-03-28)
......
......@@ -22,7 +22,6 @@ module.exports = function (grunt) {
}
}
config.coverage = grunt.option('coverage');
config.phjs = grunt.option('phjsToRelease');
config.pkg.version = grunt.option('pkgVer') || config.pkg.version;
......
coverage:
precision: 2
round: down
range: "50...100"
status:
project: yes
patch: yes
changes: no
comment:
layout: "diff"
behavior: "once"
......@@ -100,7 +100,7 @@
"gnetId": null,
"graphTooltip": 0,
"id": null,
"iteration": 1521715844826,
"iteration": 1523320861623,
"links": [],
"panels": [
{
......@@ -443,7 +443,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -522,7 +526,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -601,7 +609,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -680,7 +692,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -759,7 +775,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -838,7 +858,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -927,7 +951,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1026,7 +1054,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1115,7 +1147,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1196,7 +1232,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1285,7 +1325,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1366,7 +1410,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1455,7 +1503,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1536,7 +1588,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1619,7 +1675,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1702,7 +1762,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1792,7 +1856,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1875,7 +1943,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1965,7 +2037,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -2048,7 +2124,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -2138,7 +2218,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -2221,7 +2305,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -2311,7 +2399,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -2394,7 +2486,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
}
],
"refresh": false,
......@@ -2504,5 +2600,5 @@
"timezone": "",
"title": "Microsoft SQL Server Data Source Test",
"uid": "GlAqcPgmz",
"version": 57
"version": 58
}
\ No newline at end of file
......@@ -2,7 +2,7 @@
"__inputs": [
{
"name": "DS_MYSQL",
"label": "Mysql",
"label": "MySQL",
"description": "",
"type": "datasource",
"pluginId": "mysql",
......@@ -20,19 +20,19 @@
"type": "panel",
"id": "graph",
"name": "Graph",
"version": ""
"version": "5.0.0"
},
{
"type": "datasource",
"id": "mysql",
"name": "MySQL",
"version": "1.0.0"
"version": "5.0.0"
},
{
"type": "panel",
"id": "table",
"name": "Table",
"version": ""
"version": "5.0.0"
}
],
"annotations": {
......@@ -53,7 +53,7 @@
"gnetId": null,
"graphTooltip": 0,
"id": null,
"iteration": 1518602729468,
"iteration": 1523372133566,
"links": [],
"panels": [
{
......@@ -118,7 +118,7 @@
],
"thresholds": [],
"timeFrom": null,
"timeShift": "1h",
"timeShift": null,
"title": "Average logins / $summarize",
"tooltip": {
"shared": true,
......@@ -150,7 +150,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -204,7 +208,7 @@
],
"thresholds": [],
"timeFrom": null,
"timeShift": "1h",
"timeShift": null,
"title": "Average payments started/ended / $summarize",
"tooltip": {
"shared": true,
......@@ -236,7 +240,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -284,7 +292,7 @@
],
"thresholds": [],
"timeFrom": null,
"timeShift": "1h",
"timeShift": null,
"title": "Max CPU / $summarize",
"tooltip": {
"shared": true,
......@@ -316,7 +324,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"columns": [],
......@@ -369,7 +381,7 @@
"target": ""
}
],
"timeShift": "1h",
"timeShift": null,
"title": "Values",
"transform": "table",
"type": "table"
......@@ -428,7 +440,6 @@
"auto_count": 5,
"auto_min": "10s",
"current": {
"selected": true,
"text": "1m",
"value": "1m"
},
......@@ -545,5 +556,5 @@
"timezone": "",
"title": "Grafana Fake Data Gen - MySQL",
"uid": "DGsCac3kz",
"version": 6
"version": 8
}
\ No newline at end of file
......@@ -7,9 +7,6 @@
MYSQL_PASSWORD: password
ports:
- "3306:3306"
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
command: [mysqld, --character-set-server=utf8mb4, --collation-server=utf8mb4_unicode_ci, --innodb_monitor_enable=all]
fake-mysql-data:
......
FROM mysql:latest
ADD setup.sql /docker-entrypoint-initdb.d
CMD ["mysqld"]
\ No newline at end of file
......@@ -7,14 +7,6 @@
"type": "datasource",
"pluginId": "mysql",
"pluginName": "MySQL"
},
{
"name": "DS_MSSQL_TEST",
"label": "MSSQL Test",
"description": "",
"type": "datasource",
"pluginId": "mssql",
"pluginName": "Microsoft SQL Server"
}
],
"__requires": [
......@@ -32,12 +24,6 @@
},
{
"type": "datasource",
"id": "mssql",
"name": "Microsoft SQL Server",
"version": "1.0.0"
},
{
"type": "datasource",
"id": "mysql",
"name": "MySQL",
"version": "5.0.0"
......@@ -114,7 +100,7 @@
"gnetId": null,
"graphTooltip": 0,
"id": null,
"iteration": 1521715720483,
"iteration": 1523320712115,
"links": [],
"panels": [
{
......@@ -349,7 +335,7 @@
{
"alias": "Time",
"dateFormat": "YYYY-MM-DD HH:mm:ss",
"pattern": "time_sec",
"pattern": "time",
"type": "date"
},
{
......@@ -457,7 +443,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -536,7 +526,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -615,7 +609,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -694,7 +692,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -773,7 +775,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -852,7 +858,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -941,7 +951,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1034,7 +1048,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1123,7 +1141,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1204,7 +1226,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1293,7 +1319,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1374,7 +1404,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1463,7 +1497,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1544,7 +1582,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1634,14 +1676,18 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
"bars": true,
"dashLength": 10,
"dashes": false,
"datasource": "${DS_MSSQL_TEST}",
"datasource": "${DS_MYSQL_TEST}",
"fill": 1,
"gridPos": {
"h": 8,
......@@ -1717,7 +1763,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1807,7 +1857,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1890,7 +1944,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1980,7 +2038,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -2063,7 +2125,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -2153,7 +2219,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -2236,7 +2306,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
}
],
"refresh": false,
......@@ -2315,8 +2389,8 @@
]
},
"time": {
"from": "2018-03-15T11:30:00.000Z",
"to": "2018-03-15T12:55:01.000Z"
"from": "2018-03-15T12:30:00.000Z",
"to": "2018-03-15T13:55:01.000Z"
},
"timepicker": {
"refresh_intervals": [
......@@ -2346,5 +2420,5 @@
"timezone": "",
"title": "MySQL Data Source Test",
"uid": "Hmf8FDkmz",
"version": 9
"version": 12
}
\ No newline at end of file
mysqltests:
image: mysql:latest
build:
context: blocks/mysql_tests
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: grafana_tests
......@@ -7,7 +8,4 @@
MYSQL_PASSWORD: password
ports:
- "3306:3306"
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
tmpfs: /var/lib/mysql:rw
CREATE DATABASE grafana_ds_tests;
GRANT ALL PRIVILEGES ON grafana_ds_tests.* TO 'grafana';
FROM postgres:latest
ADD setup.sql /docker-entrypoint-initdb.d
CMD ["postgres"]
\ No newline at end of file
......@@ -100,7 +100,7 @@
"gnetId": null,
"graphTooltip": 0,
"id": null,
"iteration": 1521725946837,
"iteration": 1523320929325,
"links": [],
"panels": [
{
......@@ -443,7 +443,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -522,7 +526,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -601,7 +609,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -680,7 +692,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -759,7 +775,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -838,7 +858,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -927,7 +951,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1008,7 +1036,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1097,7 +1129,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1178,7 +1214,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1267,7 +1307,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1348,7 +1392,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1437,7 +1485,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1518,7 +1570,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1608,7 +1664,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1691,7 +1751,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1781,7 +1845,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1864,7 +1932,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -1954,7 +2026,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -2037,7 +2113,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -2127,7 +2207,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
......@@ -2210,7 +2294,11 @@
"min": null,
"show": true
}
]
],
"yaxis": {
"align": false,
"alignLevel": null
}
}
],
"refresh": false,
......
postgrestest:
image: postgres:latest
build:
context: blocks/postgres_tests
environment:
POSTGRES_USER: grafanatest
POSTGRES_PASSWORD: grafanatest
......
CREATE DATABASE grafanadstest;
REVOKE CONNECT ON DATABASE grafanadstest FROM PUBLIC;
GRANT CONNECT ON DATABASE grafanadstest TO grafanatest;
\ No newline at end of file
......@@ -102,7 +102,6 @@
"watch": "webpack --progress --colors --watch --config scripts/webpack/webpack.dev.js",
"build": "grunt build",
"test": "grunt test",
"test:coverage": "grunt test --coverage=true",
"lint": "tslint -c tslint.json --project tsconfig.json --type-check",
"karma": "grunt karma:dev",
"jest": "jest --notify --watch",
......
......@@ -258,7 +258,7 @@ func InitTestDB(t *testing.T) *xorm.Engine {
// x.ShowSQL()
if err != nil {
t.Fatalf("Failed to init in memory sqllite3 db %v", err)
t.Fatalf("Failed to init test database: %v", err)
}
sqlutil.CleanDB(x)
......@@ -269,3 +269,19 @@ func InitTestDB(t *testing.T) *xorm.Engine {
return x
}
func IsTestDbMySql() bool {
if db, present := os.LookupEnv("GRAFANA_TEST_DB"); present {
return db == dbMySql
}
return false
}
func IsTestDbPostgres() bool {
if db, present := os.LookupEnv("GRAFANA_TEST_DB"); present {
return db == dbPostgres
}
return false
}
......@@ -8,8 +8,6 @@ import (
"strconv"
"strings"
"time"
"math"
_ "github.com/denisenkom/go-mssqldb"
......@@ -231,15 +229,18 @@ func (e MssqlQueryEndpoint) transformToTimeSeries(query *tsdb.Query, rows *core.
return err
}
// converts column named time to unix timestamp in milliseconds to make
// native mysql datetime types and epoch dates work in
// annotation and table queries.
tsdb.ConvertSqlTimeColumnToEpochMs(values, timeIndex)
switch columnValue := values[timeIndex].(type) {
case int64:
timestamp = float64(columnValue * 1000)
timestamp = float64(columnValue)
case float64:
timestamp = columnValue * 1000
case time.Time:
timestamp = (float64(columnValue.Unix()) * 1000) + float64(columnValue.Nanosecond()/1e6) // in case someone is trying to map times beyond 2262 :D
timestamp = columnValue
default:
return fmt.Errorf("Invalid type for column time, must be of type timestamp or unix timestamp")
return fmt.Errorf("Invalid type for column time, must be of type timestamp or unix timestamp, got: %T %v", columnValue, columnValue)
}
if metricIndex >= 0 {
......
......@@ -8,7 +8,6 @@ import (
"math"
"reflect"
"strconv"
"time"
"github.com/go-sql-driver/mysql"
"github.com/go-xorm/core"
......@@ -239,15 +238,18 @@ func (e MysqlQueryEndpoint) transformToTimeSeries(query *tsdb.Query, rows *core.
return err
}
// converts column named time to unix timestamp in milliseconds to make
// native mysql datetime types and epoch dates work in
// annotation and table queries.
tsdb.ConvertSqlTimeColumnToEpochMs(values, timeIndex)
switch columnValue := values[timeIndex].(type) {
case int64:
timestamp = float64(columnValue * 1000)
timestamp = float64(columnValue)
case float64:
timestamp = columnValue * 1000
case time.Time:
timestamp = float64(columnValue.UnixNano() / 1e6)
timestamp = columnValue
default:
return fmt.Errorf("Invalid type for column time, must be of type timestamp or unix timestamp, got: %T %v", columnValue, columnValue)
return fmt.Errorf("Invalid type for column time/time_sec, must be of type timestamp or unix timestamp, got: %T %v", columnValue, columnValue)
}
if metricIndex >= 0 {
......
......@@ -7,7 +7,6 @@ import (
"math"
"net/url"
"strconv"
"time"
"github.com/go-xorm/core"
"github.com/grafana/grafana/pkg/components/null"
......@@ -219,13 +218,16 @@ func (e PostgresQueryEndpoint) transformToTimeSeries(query *tsdb.Query, rows *co
return err
}
// converts column named time to unix timestamp in milliseconds to make
// native mysql datetime types and epoch dates work in
// annotation and table queries.
tsdb.ConvertSqlTimeColumnToEpochMs(values, timeIndex)
switch columnValue := values[timeIndex].(type) {
case int64:
timestamp = float64(columnValue * 1000)
timestamp = float64(columnValue)
case float64:
timestamp = columnValue * 1000
case time.Time:
timestamp = float64(columnValue.UnixNano() / 1e6)
timestamp = columnValue
default:
return fmt.Errorf("Invalid type for column time, must be of type timestamp or unix timestamp, got: %T %v", columnValue, columnValue)
}
......
......@@ -135,16 +135,16 @@ func (e *DefaultSqlEngine) Query(
return result, nil
}
// ConvertTimeColumnToEpochMs converts column named time to unix timestamp in milliseconds
// ConvertSqlTimeColumnToEpochMs converts column named time to unix timestamp in milliseconds
// to make native datetime types and epoch dates work in annotation and table queries.
func ConvertSqlTimeColumnToEpochMs(values RowValues, timeIndex int) {
if timeIndex >= 0 {
switch value := values[timeIndex].(type) {
case time.Time:
values[timeIndex] = EpochPrecisionToMs(float64(value.Unix()))
values[timeIndex] = EpochPrecisionToMs(float64(value.UnixNano()))
case *time.Time:
if value != nil {
values[timeIndex] = EpochPrecisionToMs(float64((*value).Unix()))
values[timeIndex] = EpochPrecisionToMs(float64((*value).UnixNano()))
}
case int64:
values[timeIndex] = int64(EpochPrecisionToMs(float64(value)))
......@@ -152,12 +152,36 @@ func ConvertSqlTimeColumnToEpochMs(values RowValues, timeIndex int) {
if value != nil {
values[timeIndex] = int64(EpochPrecisionToMs(float64(*value)))
}
case uint64:
values[timeIndex] = int64(EpochPrecisionToMs(float64(value)))
case *uint64:
if value != nil {
values[timeIndex] = int64(EpochPrecisionToMs(float64(*value)))
}
case int32:
values[timeIndex] = int64(EpochPrecisionToMs(float64(value)))
case *int32:
if value != nil {
values[timeIndex] = int64(EpochPrecisionToMs(float64(*value)))
}
case uint32:
values[timeIndex] = int64(EpochPrecisionToMs(float64(value)))
case *uint32:
if value != nil {
values[timeIndex] = int64(EpochPrecisionToMs(float64(*value)))
}
case float64:
values[timeIndex] = EpochPrecisionToMs(value)
case *float64:
if value != nil {
values[timeIndex] = EpochPrecisionToMs(*value)
}
case float32:
values[timeIndex] = EpochPrecisionToMs(float64(value))
case *float32:
if value != nil {
values[timeIndex] = EpochPrecisionToMs(float64(*value))
}
}
}
}
package tsdb
import (
"fmt"
"testing"
"time"
......@@ -9,37 +10,177 @@ import (
func TestSqlEngine(t *testing.T) {
Convey("SqlEngine", t, func() {
Convey("Given row values with time columns when converting them", func() {
dt := time.Date(2018, 3, 14, 21, 20, 6, 527e6, time.UTC)
fixtures := make([]interface{}, 8)
dt := time.Date(2018, 3, 14, 21, 20, 6, int(527345*time.Microsecond), time.UTC)
Convey("Given row values with time.Time as time columns", func() {
var nilPointer *time.Time
fixtures := make([]interface{}, 3)
fixtures[0] = dt
fixtures[1] = dt.Unix() * 1000
fixtures[2] = dt.Unix()
fixtures[3] = float64(dt.Unix() * 1000)
fixtures[4] = float64(dt.Unix())
var nilDt *time.Time
var nilInt64 *int64
var nilFloat64 *float64
fixtures[5] = nilDt
fixtures[6] = nilInt64
fixtures[7] = nilFloat64
fixtures[1] = &dt
fixtures[2] = nilPointer
for i := range fixtures {
ConvertSqlTimeColumnToEpochMs(fixtures, i)
}
Convey("Should convert sql time columns to epoch time in ms ", func() {
expected := float64(dt.Unix() * 1000)
Convey("When converting them should return epoch time with millisecond precision ", func() {
expected := float64(dt.UnixNano()) / float64(time.Millisecond)
So(fixtures[0].(float64), ShouldEqual, expected)
So(fixtures[1].(int64), ShouldEqual, expected)
So(fixtures[2].(int64), ShouldEqual, expected)
So(fixtures[3].(float64), ShouldEqual, expected)
So(fixtures[4].(float64), ShouldEqual, expected)
So(fixtures[1].(float64), ShouldEqual, expected)
So(fixtures[2], ShouldBeNil)
})
})
So(fixtures[5], ShouldBeNil)
Convey("Given row values with int64 as time columns", func() {
tSeconds := dt.Unix()
tMilliseconds := dt.UnixNano() / 1e6
tNanoSeconds := dt.UnixNano()
var nilPointer *int64
fixtures := make([]interface{}, 7)
fixtures[0] = tSeconds
fixtures[1] = &tSeconds
fixtures[2] = tMilliseconds
fixtures[3] = &tMilliseconds
fixtures[4] = tNanoSeconds
fixtures[5] = &tNanoSeconds
fixtures[6] = nilPointer
for i := range fixtures {
ConvertSqlTimeColumnToEpochMs(fixtures, i)
}
Convey("When converting them should return epoch time with millisecond precision ", func() {
So(fixtures[0].(int64), ShouldEqual, tSeconds*1e3)
So(fixtures[1].(int64), ShouldEqual, tSeconds*1e3)
So(fixtures[2].(int64), ShouldEqual, tMilliseconds)
So(fixtures[3].(int64), ShouldEqual, tMilliseconds)
So(fixtures[4].(int64), ShouldEqual, tMilliseconds)
So(fixtures[5].(int64), ShouldEqual, tMilliseconds)
So(fixtures[6], ShouldBeNil)
So(fixtures[7], ShouldBeNil)
})
})
Convey("Given row values with uin64 as time columns", func() {
tSeconds := uint64(dt.Unix())
tMilliseconds := uint64(dt.UnixNano() / 1e6)
tNanoSeconds := uint64(dt.UnixNano())
var nilPointer *uint64
fixtures := make([]interface{}, 7)
fixtures[0] = tSeconds
fixtures[1] = &tSeconds
fixtures[2] = tMilliseconds
fixtures[3] = &tMilliseconds
fixtures[4] = tNanoSeconds
fixtures[5] = &tNanoSeconds
fixtures[6] = nilPointer
for i := range fixtures {
ConvertSqlTimeColumnToEpochMs(fixtures, i)
}
Convey("When converting them should return epoch time with millisecond precision ", func() {
So(fixtures[0].(int64), ShouldEqual, tSeconds*1e3)
So(fixtures[1].(int64), ShouldEqual, tSeconds*1e3)
So(fixtures[2].(int64), ShouldEqual, tMilliseconds)
So(fixtures[3].(int64), ShouldEqual, tMilliseconds)
So(fixtures[4].(int64), ShouldEqual, tMilliseconds)
So(fixtures[5].(int64), ShouldEqual, tMilliseconds)
So(fixtures[6], ShouldBeNil)
})
})
Convey("Given row values with int32 as time columns", func() {
tSeconds := int32(dt.Unix())
var nilInt *int32
fixtures := make([]interface{}, 3)
fixtures[0] = tSeconds
fixtures[1] = &tSeconds
fixtures[2] = nilInt
for i := range fixtures {
ConvertSqlTimeColumnToEpochMs(fixtures, i)
}
Convey("When converting them should return epoch time with millisecond precision ", func() {
So(fixtures[0].(int64), ShouldEqual, dt.Unix()*1e3)
So(fixtures[1].(int64), ShouldEqual, dt.Unix()*1e3)
So(fixtures[2], ShouldBeNil)
})
})
Convey("Given row values with uint32 as time columns", func() {
tSeconds := uint32(dt.Unix())
var nilInt *uint32
fixtures := make([]interface{}, 3)
fixtures[0] = tSeconds
fixtures[1] = &tSeconds
fixtures[2] = nilInt
for i := range fixtures {
ConvertSqlTimeColumnToEpochMs(fixtures, i)
}
Convey("When converting them should return epoch time with millisecond precision ", func() {
So(fixtures[0].(int64), ShouldEqual, dt.Unix()*1e3)
So(fixtures[1].(int64), ShouldEqual, dt.Unix()*1e3)
So(fixtures[2], ShouldBeNil)
})
})
Convey("Given row values with float64 as time columns", func() {
tSeconds := float64(dt.UnixNano()) / float64(time.Second)
tMilliseconds := float64(dt.UnixNano()) / float64(time.Millisecond)
tNanoSeconds := float64(dt.UnixNano())
var nilPointer *float64
fixtures := make([]interface{}, 7)
fixtures[0] = tSeconds
fixtures[1] = &tSeconds
fixtures[2] = tMilliseconds
fixtures[3] = &tMilliseconds
fixtures[4] = tNanoSeconds
fixtures[5] = &tNanoSeconds
fixtures[6] = nilPointer
for i := range fixtures {
ConvertSqlTimeColumnToEpochMs(fixtures, i)
}
Convey("When converting them should return epoch time with millisecond precision ", func() {
So(fixtures[0].(float64), ShouldEqual, tMilliseconds)
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)
})
})
Convey("Given row values with float32 as time columns", func() {
tSeconds := float32(dt.Unix())
var nilInt *float32
fixtures := make([]interface{}, 3)
fixtures[0] = tSeconds
fixtures[1] = &tSeconds
fixtures[2] = nilInt
for i := range fixtures {
ConvertSqlTimeColumnToEpochMs(fixtures, i)
}
Convey("When converting them should return epoch time with millisecond precision ", func() {
So(fixtures[0].(float64), ShouldEqual, float32(dt.Unix()*1e3))
So(fixtures[1].(float64), ShouldEqual, float32(dt.Unix()*1e3))
So(fixtures[2], ShouldBeNil)
})
})
})
......
......@@ -108,9 +108,14 @@ func (tr *TimeRange) ParseTo() (time.Time, error) {
// EpochPrecisionToMs converts epoch precision to millisecond, if needed.
// Only seconds to milliseconds supported right now
func EpochPrecisionToMs(value float64) float64 {
if int64(value)/1e10 == 0 {
return float64(value * 1e3)
s := strconv.FormatFloat(value, 'e', -1, 64)
if strings.HasSuffix(s, "e+09") {
return value * float64(1e3)
}
return float64(value)
if strings.HasSuffix(s, "e+18") {
return value / float64(time.Millisecond)
}
return value
}
......@@ -10,10 +10,5 @@ function exit_if_fail {
fi
}
exit_if_fail npm run test:coverage
exit_if_fail npm run build
# publish code coverage
echo "Publishing javascript code coverage"
bash <(curl -s https://codecov.io/bash) -cF javascript
rm -rf coverage
exit_if_fail npm run test
exit_if_fail npm run build
\ No newline at end of file
module.exports = function(config, grunt) {
'use strict';
var coverage = '';
if (config.coverage) {
coverage = '--coverage --maxWorkers 2';
}
return {
tslint: 'node ./node_modules/tslint/lib/tslint-cli.js -c tslint.json --project ./tsconfig.json',
jest: 'node ./node_modules/jest-cli/bin/jest.js ' + coverage,
jest: 'node ./node_modules/jest-cli/bin/jest.js --maxWorkers 2',
webpack: 'node ./node_modules/webpack/bin/webpack.js --config scripts/webpack/webpack.prod.js',
};
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment