mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
sql: remove xorm
dependency from postgres/mysql/mssql (#77870)
* sql: remove xorm * sql: remove pkg/util dependency (#78821) sql: removed md5-util dependency
This commit is contained in:
parent
d85ac7cea7
commit
9f0fc60477
@ -2,6 +2,7 @@ package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
@ -13,7 +14,6 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/tsdb/sqleng"
|
||||
@ -185,13 +185,13 @@ func TestIntegrationPostgres(t *testing.T) {
|
||||
|
||||
x := InitPostgresTestDB(t)
|
||||
|
||||
origXormEngine := sqleng.NewXormEngine
|
||||
origDB := sqleng.NewDB
|
||||
origInterpolate := sqleng.Interpolate
|
||||
t.Cleanup(func() {
|
||||
sqleng.NewXormEngine = origXormEngine
|
||||
sqleng.NewDB = origDB
|
||||
sqleng.Interpolate = origInterpolate
|
||||
})
|
||||
sqleng.NewXormEngine = func(d, c string) (*xorm.Engine, error) {
|
||||
sqleng.NewDB = func(d, c string) (*sql.DB, error) {
|
||||
return x, nil
|
||||
}
|
||||
sqleng.Interpolate = func(query backend.DataQuery, timeRange backend.TimeRange, timeInterval string, sql string) (string, error) {
|
||||
@ -229,9 +229,7 @@ func TestIntegrationPostgres(t *testing.T) {
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
sess := x.NewSession()
|
||||
t.Cleanup(sess.Close)
|
||||
db := sess.DB()
|
||||
db := x
|
||||
fromStart := time.Date(2018, 3, 15, 13, 0, 0, 0, time.UTC).In(time.Local)
|
||||
|
||||
t.Run("Given a table with different native data types", func(t *testing.T) {
|
||||
@ -615,17 +613,17 @@ func TestIntegrationPostgres(t *testing.T) {
|
||||
t.Run("Given a table with metrics having multiple values and measurements", func(t *testing.T) {
|
||||
type metric_values struct {
|
||||
Time time.Time
|
||||
TimeInt64 int64 `xorm:"bigint 'timeInt64' not null"`
|
||||
TimeInt64Nullable *int64 `xorm:"bigint 'timeInt64Nullable' null"`
|
||||
TimeFloat64 float64 `xorm:"double 'timeFloat64' not null"`
|
||||
TimeFloat64Nullable *float64 `xorm:"double 'timeFloat64Nullable' null"`
|
||||
TimeInt32 int32 `xorm:"int(11) 'timeInt32' not null"`
|
||||
TimeInt32Nullable *int32 `xorm:"int(11) 'timeInt32Nullable' null"`
|
||||
TimeFloat32 float32 `xorm:"double 'timeFloat32' not null"`
|
||||
TimeFloat32Nullable *float32 `xorm:"double 'timeFloat32Nullable' null"`
|
||||
TimeInt64 int64
|
||||
TimeInt64Nullable *int64
|
||||
TimeFloat64 float64
|
||||
TimeFloat64Nullable *float64
|
||||
TimeInt32 int32
|
||||
TimeInt32Nullable *int32
|
||||
TimeFloat32 float32
|
||||
TimeFloat32Nullable *float32
|
||||
Measurement string
|
||||
ValueOne int64 `xorm:"integer 'valueOne'"`
|
||||
ValueTwo int64 `xorm:"integer 'valueTwo'"`
|
||||
ValueOne int64
|
||||
ValueTwo int64
|
||||
}
|
||||
|
||||
_, err := db.Exec("DROP TABLE IF EXISTS metric_values")
|
||||
@ -1392,16 +1390,10 @@ func TestIntegrationPostgres(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func InitPostgresTestDB(t *testing.T) *xorm.Engine {
|
||||
func InitPostgresTestDB(t *testing.T) *sql.DB {
|
||||
connStr := postgresTestDBConnString()
|
||||
x, err := xorm.NewEngine("postgres", connStr)
|
||||
x, err := sql.Open("postgres", connStr)
|
||||
require.NoError(t, err, "Failed to init postgres DB")
|
||||
|
||||
x.DatabaseTZ = time.UTC
|
||||
x.TZLocation = time.UTC
|
||||
|
||||
// x.ShowSQL()
|
||||
|
||||
return x
|
||||
}
|
||||
|
||||
|
@ -2,34 +2,28 @@ package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"net"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
sdkproxy "github.com/grafana/grafana-plugin-sdk-go/backend/proxy"
|
||||
"github.com/grafana/grafana/pkg/tsdb/sqleng"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"github.com/lib/pq"
|
||||
"golang.org/x/net/proxy"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// createPostgresProxyDriver creates and registers a new sql driver that uses a postgres connector and updates the dialer to
|
||||
// route connections through the secure socks proxy
|
||||
func createPostgresProxyDriver(cnnstr string, opts *sdkproxy.Options) (string, error) {
|
||||
sqleng.XormDriverMu.Lock()
|
||||
defer sqleng.XormDriverMu.Unlock()
|
||||
|
||||
// create a unique driver per connection string
|
||||
hash, err := util.Md5SumString(cnnstr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
hash := fmt.Sprintf("%x", md5.Sum([]byte(cnnstr)))
|
||||
driverName := "postgres-proxy-" + hash
|
||||
|
||||
// only register the driver once
|
||||
if core.QueryDriver(driverName) == nil {
|
||||
if !slices.Contains(sql.Drivers(), driverName) {
|
||||
connector, err := pq.NewConnector(cnnstr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -41,7 +35,6 @@ func createPostgresProxyDriver(cnnstr string, opts *sdkproxy.Options) (string, e
|
||||
}
|
||||
|
||||
sql.Register(driverName, driver)
|
||||
core.RegisterDriver(driverName, driver)
|
||||
}
|
||||
return driverName, nil
|
||||
}
|
||||
@ -53,7 +46,6 @@ type postgresProxyDriver struct {
|
||||
}
|
||||
|
||||
var _ driver.DriverContext = (*postgresProxyDriver)(nil)
|
||||
var _ core.Driver = (*postgresProxyDriver)(nil)
|
||||
|
||||
// newPostgresProxyDriver updates the dialer for a postgres connector with a dialer that proxies connections through the secure socks proxy
|
||||
// and returns a new postgres driver to register
|
||||
@ -87,14 +79,6 @@ func (p *postgresProxyDialer) DialTimeout(network, address string, timeout time.
|
||||
return p.d.(proxy.ContextDialer).DialContext(ctx, network, address)
|
||||
}
|
||||
|
||||
// Parse uses the xorm postgres dialect for the driver (this has to be implemented to register the driver with xorm)
|
||||
func (d *postgresProxyDriver) Parse(a string, b string) (*core.Uri, error) {
|
||||
sqleng.XormDriverMu.RLock()
|
||||
defer sqleng.XormDriverMu.RUnlock()
|
||||
|
||||
return core.QueryDriver("postgres").Parse(a, b)
|
||||
}
|
||||
|
||||
// OpenConnector returns the normal postgres connector that has the updated dialer context
|
||||
func (d *postgresProxyDriver) OpenConnector(name string) (driver.Connector, error) {
|
||||
return d.c, nil
|
||||
|
@ -10,11 +10,9 @@ import (
|
||||
"github.com/grafana/grafana/pkg/tsdb/sqleng/proxyutil"
|
||||
"github.com/lib/pq"
|
||||
"github.com/stretchr/testify/require"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
func TestPostgresProxyDriver(t *testing.T) {
|
||||
dialect := "postgres"
|
||||
settings := proxyutil.SetupTestSecureSocksProxySettings(t)
|
||||
proxySettings := setting.SecureSocksDSProxySettings{
|
||||
Enabled: true,
|
||||
@ -42,17 +40,6 @@ func TestPostgresProxyDriver(t *testing.T) {
|
||||
require.NotEqual(t, driverName, testDriver)
|
||||
})
|
||||
|
||||
t.Run("Parse should have the same result as xorm mssql parse", func(t *testing.T) {
|
||||
xormDriver := core.QueryDriver(dialect)
|
||||
xormResult, err := xormDriver.Parse(dialect, cnnstr)
|
||||
require.NoError(t, err)
|
||||
|
||||
xormNewDriver := core.QueryDriver(driverName)
|
||||
xormNewResult, err := xormNewDriver.Parse(dialect, cnnstr)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, xormResult, xormNewResult)
|
||||
})
|
||||
|
||||
t.Run("Connector should use dialer context that routes through the socks proxy to db", func(t *testing.T) {
|
||||
connector, err := pq.NewConnector(cnnstr)
|
||||
require.NoError(t, err)
|
||||
|
@ -2,6 +2,7 @@ package mssql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
@ -12,7 +13,6 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/sqlutil"
|
||||
@ -40,12 +40,12 @@ func TestMSSQL(t *testing.T) {
|
||||
}
|
||||
|
||||
x := initMSSQLTestDB(t)
|
||||
origXormEngine := sqleng.NewXormEngine
|
||||
origDB := sqleng.NewDB
|
||||
t.Cleanup(func() {
|
||||
sqleng.NewXormEngine = origXormEngine
|
||||
sqleng.NewDB = origDB
|
||||
})
|
||||
|
||||
sqleng.NewXormEngine = func(d, c string) (*xorm.Engine, error) {
|
||||
sqleng.NewDB = func(d, c string) (*sql.DB, error) {
|
||||
return x, nil
|
||||
}
|
||||
|
||||
@ -61,9 +61,7 @@ func TestMSSQL(t *testing.T) {
|
||||
endpoint, err := sqleng.NewQueryDataHandler(setting.NewCfg(), config, &queryResultTransformer, newMssqlMacroEngine(), logger)
|
||||
require.NoError(t, err)
|
||||
|
||||
sess := x.NewSession()
|
||||
t.Cleanup(sess.Close)
|
||||
db := sess.DB()
|
||||
db := x
|
||||
|
||||
fromStart := time.Date(2018, 3, 15, 13, 0, 0, 0, time.UTC).In(time.Local)
|
||||
|
||||
@ -381,17 +379,17 @@ func TestMSSQL(t *testing.T) {
|
||||
t.Run("Given a table with metrics having multiple values and measurements", func(t *testing.T) {
|
||||
type metric_values struct {
|
||||
Time time.Time
|
||||
TimeInt64 int64 `xorm:"bigint 'timeInt64' not null"`
|
||||
TimeInt64Nullable *int64 `xorm:"bigint 'timeInt64Nullable' null"`
|
||||
TimeFloat64 float64 `xorm:"float 'timeFloat64' not null"`
|
||||
TimeFloat64Nullable *float64 `xorm:"float 'timeFloat64Nullable' null"`
|
||||
TimeInt32 int32 `xorm:"int(11) 'timeInt32' not null"`
|
||||
TimeInt32Nullable *int32 `xorm:"int(11) 'timeInt32Nullable' null"`
|
||||
TimeFloat32 float32 `xorm:"float(11) 'timeFloat32' not null"`
|
||||
TimeFloat32Nullable *float32 `xorm:"float(11) 'timeFloat32Nullable' null"`
|
||||
TimeInt64 int64
|
||||
TimeInt64Nullable *int64
|
||||
TimeFloat64 float64
|
||||
TimeFloat64Nullable *float64
|
||||
TimeInt32 int32
|
||||
TimeInt32Nullable *int32
|
||||
TimeFloat32 float32
|
||||
TimeFloat32Nullable *float32
|
||||
Measurement string
|
||||
ValueOne int64 `xorm:"integer 'valueOne'"`
|
||||
ValueTwo int64 `xorm:"integer 'valueTwo'"`
|
||||
ValueOne int64
|
||||
ValueTwo int64
|
||||
}
|
||||
|
||||
_, err := db.Exec("DROP TABLE IF EXISTS metric_values")
|
||||
@ -1481,19 +1479,14 @@ func TestGenerateConnectionString(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func initMSSQLTestDB(t *testing.T) *xorm.Engine {
|
||||
func initMSSQLTestDB(t *testing.T) *sql.DB {
|
||||
t.Helper()
|
||||
|
||||
testDB := sqlutil.MSSQLTestDB()
|
||||
x, err := xorm.NewEngine(testDB.DriverName, strings.Replace(testDB.ConnStr, "localhost",
|
||||
x, err := sql.Open(testDB.DriverName, strings.Replace(testDB.ConnStr, "localhost",
|
||||
serverIP, 1))
|
||||
require.NoError(t, err)
|
||||
|
||||
x.DatabaseTZ = time.UTC
|
||||
x.TZLocation = time.UTC
|
||||
|
||||
// x.ShowSQL()
|
||||
|
||||
return x
|
||||
}
|
||||
|
||||
|
@ -2,34 +2,28 @@ package mssql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"slices"
|
||||
|
||||
sdkproxy "github.com/grafana/grafana-plugin-sdk-go/backend/proxy"
|
||||
"github.com/grafana/grafana/pkg/tsdb/sqleng"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
mssql "github.com/microsoft/go-mssqldb"
|
||||
"golang.org/x/net/proxy"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// createMSSQLProxyDriver creates and registers a new sql driver that uses a mssql connector and updates the dialer to
|
||||
// route connections through the secure socks proxy
|
||||
func createMSSQLProxyDriver(cnnstr string, hostName string, opts *sdkproxy.Options) (string, error) {
|
||||
sqleng.XormDriverMu.Lock()
|
||||
defer sqleng.XormDriverMu.Unlock()
|
||||
|
||||
// create a unique driver per connection string
|
||||
hash, err := util.Md5SumString(cnnstr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
hash := fmt.Sprintf("%x", md5.Sum([]byte(cnnstr)))
|
||||
driverName := "mssql-proxy-" + hash
|
||||
|
||||
// only register the driver once
|
||||
if core.QueryDriver(driverName) == nil {
|
||||
if !slices.Contains(sql.Drivers(), driverName) {
|
||||
connector, err := mssql.NewConnector(cnnstr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -40,7 +34,6 @@ func createMSSQLProxyDriver(cnnstr string, hostName string, opts *sdkproxy.Optio
|
||||
return "", err
|
||||
}
|
||||
sql.Register(driverName, driver)
|
||||
core.RegisterDriver(driverName, driver)
|
||||
}
|
||||
|
||||
return driverName, nil
|
||||
@ -66,7 +59,6 @@ type mssqlProxyDriver struct {
|
||||
}
|
||||
|
||||
var _ driver.DriverContext = (*mssqlProxyDriver)(nil)
|
||||
var _ core.Driver = (*mssqlProxyDriver)(nil)
|
||||
|
||||
// newMSSQLProxyDriver updates the dialer for a mssql connector with a dialer that proxys connections through the secure socks proxy
|
||||
// and returns a new mssql driver to register
|
||||
@ -85,14 +77,6 @@ func newMSSQLProxyDriver(connector *mssql.Connector, hostName string, opts *sdkp
|
||||
return &mssqlProxyDriver{c: connector}, nil
|
||||
}
|
||||
|
||||
// Parse uses the xorm mssql dialect for the driver (this has to be implemented to register the driver with xorm)
|
||||
func (d *mssqlProxyDriver) Parse(a string, b string) (*core.Uri, error) {
|
||||
sqleng.XormDriverMu.RLock()
|
||||
defer sqleng.XormDriverMu.RUnlock()
|
||||
|
||||
return core.QueryDriver("mssql").Parse(a, b)
|
||||
}
|
||||
|
||||
// OpenConnector returns the normal mssql connector that has the updated dialer context
|
||||
func (d *mssqlProxyDriver) OpenConnector(name string) (driver.Connector, error) {
|
||||
return d.c, nil
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/tsdb/sqleng/proxyutil"
|
||||
mssql "github.com/microsoft/go-mssqldb"
|
||||
"github.com/stretchr/testify/require"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
func TestMSSQLProxyDriver(t *testing.T) {
|
||||
@ -23,7 +22,6 @@ func TestMSSQLProxyDriver(t *testing.T) {
|
||||
ProxyAddress: settings.ProxyAddress,
|
||||
ServerName: settings.ServerName,
|
||||
}
|
||||
dialect := "mssql"
|
||||
opts := proxyutil.GetSQLProxyOptions(proxySettings, sqleng.DataSourceInfo{UID: "1", JsonData: sqleng.JsonData{SecureDSProxy: true}})
|
||||
cnnstr := "server=127.0.0.1;port=1433;user id=sa;password=yourStrong(!)Password;database=db"
|
||||
driverName, err := createMSSQLProxyDriver(cnnstr, "127.0.0.1", opts)
|
||||
@ -41,17 +39,6 @@ func TestMSSQLProxyDriver(t *testing.T) {
|
||||
require.NotEqual(t, driverName, testDriver)
|
||||
})
|
||||
|
||||
t.Run("Parse should have the same result as xorm mssql parse", func(t *testing.T) {
|
||||
xormDriver := core.QueryDriver(dialect)
|
||||
xormResult, err := xormDriver.Parse(dialect, cnnstr)
|
||||
require.NoError(t, err)
|
||||
|
||||
xormNewDriver := core.QueryDriver(driverName)
|
||||
xormNewResult, err := xormNewDriver.Parse(dialect, cnnstr)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, xormResult, xormNewResult)
|
||||
})
|
||||
|
||||
t.Run("Connector should use dialer context that routes through the socks proxy to db", func(t *testing.T) {
|
||||
connector, err := mssql.NewConnector(cnnstr)
|
||||
require.NoError(t, err)
|
||||
|
@ -2,6 +2,7 @@ package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
@ -11,7 +12,6 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/stretchr/testify/require"
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/tsdb/sqleng"
|
||||
@ -39,14 +39,14 @@ func TestIntegrationMySQL(t *testing.T) {
|
||||
|
||||
x := InitMySQLTestDB(t)
|
||||
|
||||
origXormEngine := sqleng.NewXormEngine
|
||||
origDB := sqleng.NewDB
|
||||
origInterpolate := sqleng.Interpolate
|
||||
t.Cleanup(func() {
|
||||
sqleng.NewXormEngine = origXormEngine
|
||||
sqleng.NewDB = origDB
|
||||
sqleng.Interpolate = origInterpolate
|
||||
})
|
||||
|
||||
sqleng.NewXormEngine = func(d, c string) (*xorm.Engine, error) {
|
||||
sqleng.NewDB = func(d, c string) (*sql.DB, error) {
|
||||
return x, nil
|
||||
}
|
||||
|
||||
@ -77,9 +77,7 @@ func TestIntegrationMySQL(t *testing.T) {
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
sess := x.NewSession()
|
||||
t.Cleanup(sess.Close)
|
||||
db := sess.DB()
|
||||
db := x
|
||||
fromStart := time.Date(2018, 3, 15, 13, 0, 0, 0, time.UTC)
|
||||
|
||||
t.Run("Given a table with different native data types", func(t *testing.T) {
|
||||
@ -100,7 +98,7 @@ func TestIntegrationMySQL(t *testing.T) {
|
||||
sql += "`atimestamp` timestamp NOT NULL,"
|
||||
sql += "`adatetime` datetime NOT NULL,"
|
||||
sql += "`atime` time NOT NULL,"
|
||||
sql += "`ayear` year," // Crashes xorm when running cleandb
|
||||
sql += "`ayear` year,"
|
||||
sql += "`abit` bit(1),"
|
||||
sql += "`atinytext` tinytext,"
|
||||
sql += "`atinyblob` tinyblob,"
|
||||
@ -419,21 +417,21 @@ func TestIntegrationMySQL(t *testing.T) {
|
||||
|
||||
t.Run("Given a table with metrics having multiple values and measurements", func(t *testing.T) {
|
||||
type metric_values struct {
|
||||
Time time.Time `xorm:"datetime 'time' not null"`
|
||||
TimeNullable *time.Time `xorm:"datetime(6) 'timeNullable' null"`
|
||||
TimeInt64 int64 `xorm:"bigint(20) 'timeInt64' not null"`
|
||||
TimeInt64Nullable *int64 `xorm:"bigint(20) 'timeInt64Nullable' null"`
|
||||
TimeFloat64 float64 `xorm:"double 'timeFloat64' not null"`
|
||||
TimeFloat64Nullable *float64 `xorm:"double 'timeFloat64Nullable' null"`
|
||||
TimeInt32 int32 `xorm:"int(11) 'timeInt32' not null"`
|
||||
TimeInt32Nullable *int32 `xorm:"int(11) 'timeInt32Nullable' null"`
|
||||
TimeFloat32 float32 `xorm:"double 'timeFloat32' not null"`
|
||||
TimeFloat32Nullable *float32 `xorm:"double 'timeFloat32Nullable' null"`
|
||||
Time time.Time
|
||||
TimeNullable *time.Time
|
||||
TimeInt64 int64
|
||||
TimeInt64Nullable *int64
|
||||
TimeFloat64 float64
|
||||
TimeFloat64Nullable *float64
|
||||
TimeInt32 int32
|
||||
TimeInt32Nullable *int32
|
||||
TimeFloat32 float32
|
||||
TimeFloat32Nullable *float32
|
||||
Measurement string
|
||||
ValueOne int64 `xorm:"integer 'valueOne'"`
|
||||
ValueTwo int64 `xorm:"integer 'valueTwo'"`
|
||||
ValueThree int64 `xorm:"tinyint(1) null 'valueThree'"`
|
||||
ValueFour int64 `xorm:"smallint(1) null 'valueFour'"`
|
||||
ValueOne int64
|
||||
ValueTwo int64
|
||||
ValueThree int64
|
||||
ValueFour int64
|
||||
}
|
||||
|
||||
_, err := db.Exec("DROP TABLE IF EXISTS metric_values")
|
||||
@ -1291,18 +1289,13 @@ func TestIntegrationMySQL(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func InitMySQLTestDB(t *testing.T) *xorm.Engine {
|
||||
func InitMySQLTestDB(t *testing.T) *sql.DB {
|
||||
connStr := mySQLTestDBConnStr()
|
||||
x, err := xorm.NewEngine("mysql", connStr)
|
||||
x, err := sql.Open("mysql", connStr)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to init mysql db %v", err)
|
||||
}
|
||||
|
||||
x.DatabaseTZ = time.UTC
|
||||
x.TZLocation = time.UTC
|
||||
|
||||
// x.ShowSQL()
|
||||
|
||||
return x
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,12 @@ package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/go-sql-driver/mysql"
|
||||
sdkproxy "github.com/grafana/grafana-plugin-sdk-go/backend/proxy"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"golang.org/x/net/proxy"
|
||||
)
|
||||
|
||||
@ -21,10 +22,7 @@ func registerProxyDialerContext(protocol, cnnstr string, opts *sdkproxy.Options)
|
||||
|
||||
// the dialer context can be updated everytime the datasource is updated
|
||||
// have a unique network per connection string
|
||||
hash, err := util.Md5SumString(cnnstr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
hash := fmt.Sprintf("%x", md5.Sum([]byte(cnnstr)))
|
||||
network := "proxy-" + hash
|
||||
mysql.RegisterDialContext(network, dialer.DialContext)
|
||||
|
||||
|
@ -16,8 +16,6 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data/sqlutil"
|
||||
"xorm.io/core"
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
@ -25,9 +23,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/util/errutil"
|
||||
)
|
||||
|
||||
// XormDriverMu is used to allow safe concurrent registering and querying of drivers in xorm
|
||||
var XormDriverMu sync.RWMutex
|
||||
|
||||
// MetaKeyExecutedQueryString is the key where the executed query should get stored
|
||||
const MetaKeyExecutedQueryString = "executedQueryString"
|
||||
|
||||
@ -48,11 +43,11 @@ type SqlQueryResultTransformer interface {
|
||||
|
||||
var sqlIntervalCalculator = intervalv2.NewCalculator()
|
||||
|
||||
// NewXormEngine is an xorm.Engine factory, that can be stubbed by tests.
|
||||
// NewDB is a sql.DB factory, that can be stubbed by tests.
|
||||
//
|
||||
//nolint:gocritic
|
||||
var NewXormEngine = func(driverName string, connectionString string) (*xorm.Engine, error) {
|
||||
return xorm.NewEngine(driverName, connectionString)
|
||||
var NewDB = func(driverName string, connectionString string) (*sql.DB, error) {
|
||||
return sql.Open(driverName, connectionString)
|
||||
}
|
||||
|
||||
type JsonData struct {
|
||||
@ -89,13 +84,6 @@ type DataSourceInfo struct {
|
||||
DecryptedSecureJSONData map[string]string
|
||||
}
|
||||
|
||||
// Defaults for the xorm connection pool
|
||||
type DefaultConnectionInfo struct {
|
||||
MaxOpenConns int
|
||||
MaxIdleConns int
|
||||
ConnMaxLifetime int
|
||||
}
|
||||
|
||||
type DataPluginConfiguration struct {
|
||||
DriverName string
|
||||
DSInfo DataSourceInfo
|
||||
@ -108,7 +96,7 @@ type DataPluginConfiguration struct {
|
||||
type DataSourceHandler struct {
|
||||
macroEngine SQLMacroEngine
|
||||
queryResultTransformer SqlQueryResultTransformer
|
||||
engine *xorm.Engine
|
||||
db *sql.DB
|
||||
timeColumnNames []string
|
||||
metricColumnTypes []string
|
||||
log log.Logger
|
||||
@ -165,16 +153,16 @@ func NewQueryDataHandler(cfg *setting.Cfg, config DataPluginConfiguration, query
|
||||
queryDataHandler.metricColumnTypes = config.MetricColumnTypes
|
||||
}
|
||||
|
||||
engine, err := NewXormEngine(config.DriverName, config.ConnectionString)
|
||||
db, err := NewDB(config.DriverName, config.ConnectionString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
engine.SetMaxOpenConns(config.DSInfo.JsonData.MaxOpenConns)
|
||||
engine.SetMaxIdleConns(config.DSInfo.JsonData.MaxIdleConns)
|
||||
engine.SetConnMaxLifetime(time.Duration(config.DSInfo.JsonData.ConnMaxLifetime) * time.Second)
|
||||
db.SetMaxOpenConns(config.DSInfo.JsonData.MaxOpenConns)
|
||||
db.SetMaxIdleConns(config.DSInfo.JsonData.MaxIdleConns)
|
||||
db.SetConnMaxLifetime(time.Duration(config.DSInfo.JsonData.ConnMaxLifetime) * time.Second)
|
||||
|
||||
queryDataHandler.engine = engine
|
||||
queryDataHandler.db = db
|
||||
return &queryDataHandler, nil
|
||||
}
|
||||
|
||||
@ -184,17 +172,17 @@ type DBDataResponse struct {
|
||||
}
|
||||
|
||||
func (e *DataSourceHandler) Dispose() {
|
||||
e.log.Debug("Disposing engine...")
|
||||
if e.engine != nil {
|
||||
if err := e.engine.Close(); err != nil {
|
||||
e.log.Error("Failed to dispose engine", "error", err)
|
||||
e.log.Debug("Disposing DB...")
|
||||
if e.db != nil {
|
||||
if err := e.db.Close(); err != nil {
|
||||
e.log.Error("Failed to dispose db", "error", err)
|
||||
}
|
||||
}
|
||||
e.log.Debug("Engine disposed")
|
||||
e.log.Debug("DB disposed")
|
||||
}
|
||||
|
||||
func (e *DataSourceHandler) Ping() error {
|
||||
return e.engine.Ping()
|
||||
return e.db.Ping()
|
||||
}
|
||||
|
||||
func (e *DataSourceHandler) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
@ -285,11 +273,7 @@ func (e *DataSourceHandler) executeQuery(query backend.DataQuery, wg *sync.WaitG
|
||||
return
|
||||
}
|
||||
|
||||
session := e.engine.NewSession()
|
||||
defer session.Close()
|
||||
db := session.DB()
|
||||
|
||||
rows, err := db.QueryContext(queryContext, interpolatedQuery)
|
||||
rows, err := e.db.QueryContext(queryContext, interpolatedQuery)
|
||||
if err != nil {
|
||||
errAppendDebug("db query error", e.TransformQueryError(logger, err), interpolatedQuery)
|
||||
return
|
||||
@ -308,7 +292,7 @@ func (e *DataSourceHandler) executeQuery(query backend.DataQuery, wg *sync.WaitG
|
||||
|
||||
// Convert row.Rows to dataframe
|
||||
stringConverters := e.queryResultTransformer.GetConverterList()
|
||||
frame, err := sqlutil.FrameFromRows(rows.Rows, e.rowLimit, sqlutil.ToConverters(stringConverters...)...)
|
||||
frame, err := sqlutil.FrameFromRows(rows, e.rowLimit, sqlutil.ToConverters(stringConverters...)...)
|
||||
if err != nil {
|
||||
errAppendDebug("convert frame from rows error", err, interpolatedQuery)
|
||||
return
|
||||
@ -418,7 +402,7 @@ var Interpolate = func(query backend.DataQuery, timeRange backend.TimeRange, tim
|
||||
}
|
||||
|
||||
func (e *DataSourceHandler) newProcessCfg(query backend.DataQuery, queryContext context.Context,
|
||||
rows *core.Rows, interpolatedQuery string) (*dataQueryModel, error) {
|
||||
rows *sql.Rows, interpolatedQuery string) (*dataQueryModel, error) {
|
||||
columnNames, err := rows.Columns()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -431,7 +415,6 @@ func (e *DataSourceHandler) newProcessCfg(query backend.DataQuery, queryContext
|
||||
qm := &dataQueryModel{
|
||||
columnTypes: columnTypes,
|
||||
columnNames: columnNames,
|
||||
rows: rows,
|
||||
timeIndex: -1,
|
||||
timeEndIndex: -1,
|
||||
metricIndex: -1,
|
||||
@ -525,7 +508,6 @@ type dataQueryModel struct {
|
||||
timeIndex int
|
||||
timeEndIndex int
|
||||
metricIndex int
|
||||
rows *core.Rows
|
||||
metricPrefix bool
|
||||
queryContext context.Context
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user