mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
More progress on db schema setup and migrations, tricky stuff
This commit is contained in:
parent
38f237efcb
commit
68a77c4051
@ -1,7 +1,9 @@
|
||||
db:
|
||||
mysql:
|
||||
image: mysql:latest
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: rootpass
|
||||
MYSQL_DATABASE: grafana
|
||||
MYSQL_USER: grafana
|
||||
MYSQL_PASSWORD: password
|
||||
ports:
|
||||
- "3306:3306"
|
||||
|
9
docker/blocks/mysql_tests/fig
Normal file
9
docker/blocks/mysql_tests/fig
Normal file
@ -0,0 +1,9 @@
|
||||
mysqltests:
|
||||
image: mysql:latest
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: rootpass
|
||||
MYSQL_DATABASE: grafana_tests
|
||||
MYSQL_USER: grafana
|
||||
MYSQL_PASSWORD: password
|
||||
ports:
|
||||
- "3306:3306"
|
@ -1,10 +1,10 @@
|
||||
openldap:
|
||||
image: cnry/openldap
|
||||
mysqltests:
|
||||
image: mysql:latest
|
||||
environment:
|
||||
SLAPD_PASSWORD: grafana
|
||||
SLAPD_DOMAIN: grafana.org
|
||||
MYSQL_ROOT_PASSWORD: rootpass
|
||||
MYSQL_DATABASE: grafana_tests
|
||||
MYSQL_USER: grafana
|
||||
MYSQL_PASSWORD: password
|
||||
ports:
|
||||
- "389:389"
|
||||
|
||||
|
||||
- "3306:3306"
|
||||
|
||||
|
@ -8,9 +8,8 @@ import (
|
||||
|
||||
func GetAccount(c *middleware.Context) {
|
||||
query := m.GetAccountInfoQuery{Id: c.AccountId}
|
||||
err := bus.Dispatch(&query)
|
||||
|
||||
if err != nil {
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
c.JsonApiErr(500, "Failed to fetch collaboratos", err)
|
||||
return
|
||||
}
|
||||
@ -31,9 +30,8 @@ func UpdateAccount(c *middleware.Context, cmd m.UpdateAccountCommand) {
|
||||
|
||||
func GetOtherAccounts(c *middleware.Context) {
|
||||
query := m.GetOtherAccountsQuery{AccountId: c.AccountId}
|
||||
err := bus.Dispatch(&query)
|
||||
|
||||
if err != nil {
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
c.JsonApiErr(500, "Failed to get other accounts", err)
|
||||
return
|
||||
}
|
||||
|
@ -3,9 +3,27 @@ package migrations
|
||||
type migration struct {
|
||||
desc string
|
||||
sqlite string
|
||||
mysql string
|
||||
verifyTable string
|
||||
}
|
||||
|
||||
type columnType string
|
||||
|
||||
const (
|
||||
DB_TYPE_STRING columnType = "String"
|
||||
)
|
||||
|
||||
func (m *migration) getSql(dbType string) string {
|
||||
switch dbType {
|
||||
case "mysql":
|
||||
return m.mysql
|
||||
case "sqlite3":
|
||||
return m.sqlite
|
||||
}
|
||||
|
||||
panic("db type not supported")
|
||||
}
|
||||
|
||||
type migrationBuilder struct {
|
||||
migration *migration
|
||||
}
|
||||
@ -15,6 +33,11 @@ func (b *migrationBuilder) sqlite(sql string) *migrationBuilder {
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *migrationBuilder) mysql(sql string) *migrationBuilder {
|
||||
b.migration.mysql = sql
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *migrationBuilder) verifyTable(name string) *migrationBuilder {
|
||||
b.migration.verifyTable = name
|
||||
return b
|
||||
|
@ -4,8 +4,12 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
"github.com/torkelo/grafana-pro/pkg/services/sqlstore/sqlsyntax"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/go-xorm/xorm"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
var x *xorm.Engine
|
||||
@ -29,9 +33,18 @@ func getSchemaVersion() (int, error) {
|
||||
return v.Version, err
|
||||
}
|
||||
|
||||
func StartMigration(engine *xorm.Engine) error {
|
||||
func setEngineAndDialect(engine *xorm.Engine) {
|
||||
x = engine
|
||||
dialect = new(sqlsyntax.Sqlite3)
|
||||
switch x.DriverName() {
|
||||
case "mysql":
|
||||
dialect = new(sqlsyntax.Mysql)
|
||||
case "sqlite3":
|
||||
dialect = new(sqlsyntax.Sqlite3)
|
||||
}
|
||||
}
|
||||
|
||||
func StartMigration(engine *xorm.Engine) error {
|
||||
setEngineAndDialect(engine)
|
||||
|
||||
_, err := getSchemaVersion()
|
||||
if err != nil {
|
||||
@ -49,16 +62,21 @@ func StartMigration(engine *xorm.Engine) error {
|
||||
|
||||
func execMigration(m *migration) error {
|
||||
err := inTransaction(func(sess *xorm.Session) error {
|
||||
_, err := sess.Exec(m.sqlite)
|
||||
_, err := sess.Exec(m.getSql(x.DriverName()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// verify
|
||||
|
||||
return verifyMigration(m)
|
||||
}
|
||||
|
||||
func verifyMigration(m *migration) error {
|
||||
if m.verifyTable != "" {
|
||||
sqlStr, args := dialect.TableCheckSql(m.verifyTable)
|
||||
results, err := x.Query(sqlStr, args...)
|
||||
@ -66,7 +84,6 @@ func execMigration(m *migration) error {
|
||||
return errors.New(fmt.Sprintf("Verify failed: table %v does not exist", m.verifyTable))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -4,13 +4,24 @@ var migrationList []*migration
|
||||
|
||||
func init() {
|
||||
new(migrationBuilder).
|
||||
// ------------------------------
|
||||
desc("Create account table").
|
||||
sqlite(`
|
||||
CREATE TABLE account (
|
||||
id INTEGER PRIMARY KEY
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
)
|
||||
`).
|
||||
verifyTable("account")
|
||||
mysql(`
|
||||
CREATE TABLE account (
|
||||
id BIGINT NOT NULL AUTO_INCREMENT, PRIMARY KEY (id)
|
||||
)
|
||||
`).
|
||||
verifyTable("account").add()
|
||||
// ------------------------------
|
||||
// desc("Add name column to account table").
|
||||
// table("account").addColumn("name").colType(DB_TYPE_STRING)
|
||||
// sqlite("ALTER TABLE account ADD COLUMN name TEXT").
|
||||
// mysql("ALTER TABLE account ADD COLUMN name NVARCHAR(255)").
|
||||
}
|
||||
|
||||
type SchemaVersion struct {
|
||||
|
@ -1,22 +1,55 @@
|
||||
package migrations
|
||||
|
||||
// import (
|
||||
// "testing"
|
||||
//
|
||||
// "github.com/go-xorm/xorm"
|
||||
//
|
||||
// . "github.com/smartystreets/goconvey/convey"
|
||||
// )
|
||||
//
|
||||
// func TestMigrationsSqlite(t *testing.T) {
|
||||
//
|
||||
// Convey("Initial SQLite3 migration", t, func() {
|
||||
// x, err := xorm.NewEngine("sqlite3", ":memory:")
|
||||
// StartMigration(x)
|
||||
//
|
||||
// tables, err := x.DBMetas()
|
||||
// So(err, ShouldBeNil)
|
||||
//
|
||||
// So(len(tables), ShouldEqual, 1)
|
||||
// })
|
||||
// }
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func cleanDB(x *xorm.Engine) {
|
||||
tables, _ := x.DBMetas()
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
|
||||
for _, table := range tables {
|
||||
if _, err := sess.Exec("SET FOREIGN_KEY_CHECKS = 0"); err != nil {
|
||||
panic("Failed to disable foreign key checks")
|
||||
}
|
||||
if _, err := sess.Exec("DROP TABLE " + table.Name); err != nil {
|
||||
panic(fmt.Sprintf("Failed to delete table: %v, err: %v", table.Name, err))
|
||||
}
|
||||
if _, err := sess.Exec("SET FOREIGN_KEY_CHECKS = 1"); err != nil {
|
||||
panic("Failed to disable foreign key checks")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMigrationsSqlite(t *testing.T) {
|
||||
testDBs := [][]string{
|
||||
[]string{"sqlite3", ":memory:"},
|
||||
[]string{"mysql", "grafana:password@tcp(localhost:3306)/grafana_tests?charset=utf8"},
|
||||
}
|
||||
|
||||
for _, testDB := range testDBs {
|
||||
|
||||
Convey("Initial "+testDB[0]+" migration", t, func() {
|
||||
x, err := xorm.NewEngine(testDB[0], testDB[1])
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
if testDB[0] == "mysql" {
|
||||
cleanDB(x)
|
||||
}
|
||||
|
||||
StartMigration(x)
|
||||
|
||||
tables, err := x.DBMetas()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(tables), ShouldEqual, 2)
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -8,11 +8,24 @@ type Dialect interface {
|
||||
type Sqlite3 struct {
|
||||
}
|
||||
|
||||
type Mysql struct {
|
||||
}
|
||||
|
||||
func (db *Sqlite3) DBType() string {
|
||||
return "sqlite3"
|
||||
}
|
||||
|
||||
func (db *Mysql) DBType() string {
|
||||
return "mysql"
|
||||
}
|
||||
|
||||
func (db *Sqlite3) TableCheckSql(tableName string) (string, []interface{}) {
|
||||
args := []interface{}{tableName}
|
||||
return "SELECT name FROM sqlite_master WHERE type='table' and name = ?", args
|
||||
}
|
||||
|
||||
func (db *Mysql) TableCheckSql(tableName string) (string, []interface{}) {
|
||||
args := []interface{}{"grafana", tableName}
|
||||
sql := "SELECT `TABLE_NAME` from `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_SCHEMA`=? and `TABLE_NAME`=?"
|
||||
return sql, args
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user