浏览代码

More work on SQL migrations

Torkel Ödegaard 10 年之前
父节点
当前提交
ed68a4bb9a

+ 65 - 62
pkg/services/sqlstore/migrations/apikey_mig.go

@@ -3,70 +3,73 @@ package migrations
 import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
 
 func addApiKeyMigrations(mg *Migrator) {
-	mg.AddMigration("create api_key table", new(AddTableMigration).
-		Name("api_key").WithColumns(
-		&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
-		&Column{Name: "account_id", Type: DB_BigInt, Nullable: false},
-		&Column{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "key", Type: DB_Varchar, Length: 64, Nullable: false},
-		&Column{Name: "role", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "created", Type: DB_DateTime, Nullable: false},
-		&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
-	))
-
-	//-------  indexes ------------------
-	mg.AddMigration("add index api_key.account_id", new(AddIndexMigration).
-		Table("api_key").Columns("account_id"))
-
-	mg.AddMigration("add index api_key.key", new(AddIndexMigration).
-		Table("api_key").Columns("key").Unique())
-
-	mg.AddMigration("add index api_key.account_id_name", new(AddIndexMigration).
-		Table("api_key").Columns("account_id", "name").Unique())
+	apiKeyV1 := Table{
+		Name: "api_key",
+		Columns: []*Column{
+			&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
+			&Column{Name: "account_id", Type: DB_BigInt, Nullable: false},
+			&Column{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "key", Type: DB_Varchar, Length: 64, Nullable: false},
+			&Column{Name: "role", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "created", Type: DB_DateTime, Nullable: false},
+			&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
+		},
+		Indices: []*Index{
+			&Index{Cols: []string{"account_id"}},
+			&Index{Cols: []string{"key"}, Type: UniqueIndex},
+			&Index{Cols: []string{"account_id", "name"}, Type: UniqueIndex},
+		},
+	}
+
+	// create table
+	mg.AddMigration("create api_key table", NewAddTableMigration(apiKeyV1))
+	// create indices
+	mg.AddMigration("add index api_key.account_id", NewAddIndexMigration(apiKeyV1, apiKeyV1.Indices[0]))
+	mg.AddMigration("add index api_key.key", NewAddIndexMigration(apiKeyV1, apiKeyV1.Indices[1]))
+	mg.AddMigration("add index api_key.account_id_name", NewAddIndexMigration(apiKeyV1, apiKeyV1.Indices[2]))
 
 	// ---------------------
 	// account -> org changes
 
-	//-------  drop indexes ------------------
-	mg.AddMigration("drop index api_key.account_id", new(DropIndexMigration).
-		Table("api_key").Columns("account_id"))
-
-	mg.AddMigration("drop index api_key.key", new(DropIndexMigration).
-		Table("api_key").Columns("key").Unique())
-
-	mg.AddMigration("drop index api_key.account_id_name", new(DropIndexMigration).
-		Table("api_key").Columns("account_id", "name").Unique())
-
-	//------- rename table ------------------
-	mg.AddMigration("rename table api_key to api_key_old", new(RenameTableMigration).
-		Rename("api_key", "api_key_old"))
-
-	//------- recreate table with new column names ------------------
-	mg.AddMigration("create api_key table v2", new(AddTableMigration).
-		Name("api_key").WithColumns(
-		&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
-		&Column{Name: "org_id", Type: DB_BigInt, Nullable: false},
-		&Column{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "key", Type: DB_Varchar, Length: 64, Nullable: false},
-		&Column{Name: "role", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "created", Type: DB_DateTime, Nullable: false},
-		&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
-	))
-
-	//------- recreate indexes ------------------
-	mg.AddMigration("add index api_key.org_id", new(AddIndexMigration).
-		Table("api_key").Columns("org_id"))
-
-	mg.AddMigration("add index api_key.key v2", new(AddIndexMigration).
-		Table("api_key").Columns("key").Unique())
-
-	mg.AddMigration("add index api_key.org_id_name", new(AddIndexMigration).
-		Table("api_key").Columns("org_id", "name").Unique())
-
-	//------- copy data from old api_key_old -------------------
-	mg.AddMigration("copy data from old api_key table", new(CopyTableDataMigration).
-		Source("api_key_old", "id, account_id, name, key, role, created, updated").
-		Target("api_key", "id, org_id, name, key, role, created, updated"))
-
-	mg.AddMigration("Drop old table api_key_old", new(DropTableMigration).Table("api_key_old"))
+	// drop indexes
+	addDropAllIndicesMigrations(mg, "v1", apiKeyV1)
+	// rename table
+	addTableRenameMigration(mg, "api_key", "api_key_v1", "v1")
+
+	apiKeyV2 := Table{
+		Name: "api_key",
+		Columns: []*Column{
+			&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
+			&Column{Name: "org_id", Type: DB_BigInt, Nullable: false},
+			&Column{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "key", Type: DB_Varchar, Length: 64, Nullable: false},
+			&Column{Name: "role", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "created", Type: DB_DateTime, Nullable: false},
+			&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
+		},
+		Indices: []*Index{
+			&Index{Cols: []string{"org_id"}},
+			&Index{Cols: []string{"key"}, Type: UniqueIndex},
+			&Index{Cols: []string{"org_id", "name"}, Type: UniqueIndex},
+		},
+	}
+
+	// create v2 table
+	mg.AddMigration("create api_key table v2", NewAddTableMigration(apiKeyV2))
+
+	// add v2 indíces
+	addTableIndicesMigrations(mg, "v2", apiKeyV2)
+
+	//------- copy data from v1 to v2 -------------------
+	mg.AddMigration("copy api_key v1 to v2", NewCopyTableDataMigration("api_key", "api_key_v1", map[string]string{
+		"id":      "id",
+		"org_id":  "account_id",
+		"name":    "name",
+		"key":     "key",
+		"role":    "role",
+		"created": "created",
+		"updated": "updated",
+	}))
+
+	mg.AddMigration("Drop old table api_key_v1", NewDropTableMigration("api_key_v1"))
 }

+ 27 - 0
pkg/services/sqlstore/migrations/common.go

@@ -0,0 +1,27 @@
+package migrations
+
+import (
+	"fmt"
+
+	. "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
+)
+
+func addDropAllIndicesMigrations(mg *Migrator, versionSuffix string, table Table) {
+	for _, index := range table.Indices {
+		migrationId := fmt.Sprintf("drop index %s - %s", index.XName(table.Name), versionSuffix)
+		mg.AddMigration(migrationId, NewDropIndexMigration(table, index))
+	}
+}
+
+func addTableIndicesMigrations(mg *Migrator, versionSuffix string, table Table) {
+	for _, index := range table.Indices {
+		migration := NewAddIndexMigration(table, index)
+		migrationId := fmt.Sprintf("create index %s - %s", index.XName(table.Name), versionSuffix)
+		mg.AddMigration(migrationId, migration)
+	}
+}
+
+func addTableRenameMigration(mg *Migrator, oldName string, newName string, versionSuffix string) {
+	migrationId := fmt.Sprintf("Rename table %s to %s - %s", oldName, newName, versionSuffix)
+	mg.AddMigration(migrationId, NewRenameTableMigration(oldName, newName))
+}

+ 76 - 68
pkg/services/sqlstore/migrations/dashboard_mig.go

@@ -3,79 +3,87 @@ package migrations
 import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
 
 func addDashboardMigration(mg *Migrator) {
-	mg.AddMigration("create dashboard table", new(AddTableMigration).
-		Name("dashboard").WithColumns(
-		&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
-		&Column{Name: "version", Type: DB_Int, Nullable: false},
-		&Column{Name: "slug", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "title", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "data", Type: DB_Text, Nullable: false},
-		&Column{Name: "account_id", Type: DB_BigInt, Nullable: false},
-		&Column{Name: "created", Type: DB_DateTime, Nullable: false},
-		&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
-	))
-
-	mg.AddMigration("create dashboard_tag table", new(AddTableMigration).
-		Name("dashboard_tag").WithColumns(
-		&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
-		&Column{Name: "dashboard_id", Type: DB_BigInt, Nullable: false},
-		&Column{Name: "term", Type: DB_NVarchar, Length: 50, Nullable: false},
-	))
+	var dashboardV1 = Table{
+		Name: "dashboard",
+		Columns: []*Column{
+			&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
+			&Column{Name: "version", Type: DB_Int, Nullable: false},
+			&Column{Name: "slug", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "title", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "data", Type: DB_Text, Nullable: false},
+			&Column{Name: "account_id", Type: DB_BigInt, Nullable: false},
+			&Column{Name: "created", Type: DB_DateTime, Nullable: false},
+			&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
+		},
+		Indices: []*Index{
+			&Index{Cols: []string{"account_id"}},
+			&Index{Cols: []string{"account_id", "slug"}, Type: UniqueIndex},
+		},
+	}
+
+	mg.AddMigration("create dashboard table", NewAddTableMigration(dashboardV1))
 
 	//-------  indexes ------------------
-	mg.AddMigration("add index dashboard.account_id", new(AddIndexMigration).
-		Table("dashboard").Columns("account_id"))
-
-	mg.AddMigration("add unique index dashboard_account_id_slug", new(AddIndexMigration).
-		Table("dashboard").Columns("account_id", "slug").Unique())
-
-	mg.AddMigration("add unique index dashboard_tag.dasboard_id_term", new(AddIndexMigration).
-		Table("dashboard_tag").Columns("dashboard_id", "term").Unique())
+	mg.AddMigration("add index dashboard.account_id", NewAddIndexMigration(dashboardV1, dashboardV1.Indices[0]))
+	mg.AddMigration("add unique index dashboard_account_id_slug", NewAddIndexMigration(dashboardV1, dashboardV1.Indices[1]))
+
+	dashboardTagV1 := Table{
+		Name: "dashboard_tag",
+		Columns: []*Column{
+			&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
+			&Column{Name: "dashboard_id", Type: DB_BigInt, Nullable: false},
+			&Column{Name: "term", Type: DB_NVarchar, Length: 50, Nullable: false},
+		},
+		Indices: []*Index{
+			&Index{Cols: []string{"dashboard_id", "term"}, Type: UniqueIndex},
+		},
+	}
+
+	mg.AddMigration("create dashboard_tag table", NewAddTableMigration(dashboardTagV1))
+	mg.AddMigration("add unique index dashboard_tag.dasboard_id_term", NewAddIndexMigration(dashboardTagV1, dashboardTagV1.Indices[0]))
 
 	// ---------------------
 	// account -> org changes
 
-	//-------  drop indexes ------------------
-	mg.AddMigration("drop index dashboard.account_id", new(DropIndexMigration).
-		Table("dashboard").Columns("account_id"))
-
-	mg.AddMigration("drop unique index dashboard_account_id_slug", new(DropIndexMigration).
-		Table("dashboard").Columns("account_id", "slug").Unique())
-
-	mg.AddMigration("drop unique index dashboard_tag.dasboard_id_term", new(DropIndexMigration).
-		Table("dashboard_tag").Columns("dashboard_id", "term").Unique())
-
+	//-------  drop dashboard indexes ------------------
+	addDropAllIndicesMigrations(mg, "v1", dashboardTagV1)
 	//------- rename table ------------------
-	mg.AddMigration("rename table dashboard to dashboard_old", new(RenameTableMigration).
-		Rename("dashboard", "dashboard_old"))
-
-	//------- recreate table with new column names ------------------
-	mg.AddMigration("create dashboard table v2", new(AddTableMigration).
-		Name("dashboard").WithColumns(
-		&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
-		&Column{Name: "version", Type: DB_Int, Nullable: false},
-		&Column{Name: "slug", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "title", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "data", Type: DB_Text, Nullable: false},
-		&Column{Name: "org_id", Type: DB_BigInt, Nullable: false},
-		&Column{Name: "created", Type: DB_DateTime, Nullable: false},
-		&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
-	))
-
-	//-------  dashboard table indexes ------------------
-	mg.AddMigration("add index dashboard.org_id", new(AddIndexMigration).
-		Table("dashboard").Columns("org_id"))
-
-	mg.AddMigration("add unique index dashboard_org_id_slug", new(AddIndexMigration).
-		Table("dashboard").Columns("org_id", "slug").Unique())
-
-	mg.AddMigration("add unique index dashboard_tag.dasboard_id_term v2", new(AddIndexMigration).
-		Table("dashboard_tag").Columns("dashboard_id", "term").Unique())
-
-	//------- copy data from table -------------------
-	mg.AddMigration("copy data from dashboard_old table", new(CopyTableDataMigration).
-		Source("dashboard_old", "id, version, slug, title, data, account_id, created, updated").
-		Target("dashboard", "id, version, slug, title, data, org_id, created, updated"))
-
-	mg.AddMigration("Drop old table dashboard_old", new(DropTableMigration).Table("dashboard_old"))
+	addTableRenameMigration(mg, "dashboard", "dashboard_v1", "v1")
+
+	// dashboard v2
+	var dashboardV2 = Table{
+		Name: "dashboard",
+		Columns: []*Column{
+			&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
+			&Column{Name: "version", Type: DB_Int, Nullable: false},
+			&Column{Name: "slug", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "title", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "data", Type: DB_Text, Nullable: false},
+			&Column{Name: "org_id", Type: DB_BigInt, Nullable: false},
+			&Column{Name: "created", Type: DB_DateTime, Nullable: false},
+			&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
+		},
+		Indices: []*Index{
+			&Index{Cols: []string{"org_id"}},
+			&Index{Cols: []string{"org_id", "slug"}, Type: UniqueIndex},
+		},
+	}
+
+	// recreate table
+	mg.AddMigration("create dashboard v2", NewAddTableMigration(dashboardV2))
+	// recreate indices
+	addTableIndicesMigrations(mg, "v2", dashboardV2)
+	// copy data
+	mg.AddMigration("copy dashboard v1 to v2", NewCopyTableDataMigration("dashboard", "dashboard_v1", map[string]string{
+		"id":      "id",
+		"version": "version",
+		"slug":    "slug",
+		"title":   "title",
+		"data":    "data",
+		"org_id":  "account_id",
+		"created": "created",
+		"updated": "updated",
+	}))
+
+	mg.AddMigration("drop table dashboard_v1", NewDropTableMigration("dashboard_v1"))
 }

+ 82 - 66
pkg/services/sqlstore/migrations/datasource_mig.go

@@ -3,80 +3,96 @@ package migrations
 import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
 
 func addDataSourceMigration(mg *Migrator) {
-	mg.AddMigration("create data_source table", new(AddTableMigration).
-		Name("data_source").WithColumns(
-		&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
-		&Column{Name: "account_id", Type: DB_BigInt, Nullable: false},
-		&Column{Name: "version", Type: DB_Int, Nullable: false},
-		&Column{Name: "type", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "access", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "url", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "password", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "user", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "database", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "basic_auth", Type: DB_Bool, Nullable: false},
-		&Column{Name: "basic_auth_user", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "basic_auth_password", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "is_default", Type: DB_Bool, Nullable: false},
-		&Column{Name: "created", Type: DB_DateTime, Nullable: false},
-		&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
-	))
+	var tableV1 = Table{
+		Name: "data_source",
+		Columns: []*Column{
+			&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
+			&Column{Name: "account_id", Type: DB_BigInt, Nullable: false},
+			&Column{Name: "version", Type: DB_Int, Nullable: false},
+			&Column{Name: "type", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "access", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "url", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "password", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "user", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "database", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "basic_auth", Type: DB_Bool, Nullable: false},
+			&Column{Name: "basic_auth_user", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "basic_auth_password", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "is_default", Type: DB_Bool, Nullable: false},
+			&Column{Name: "created", Type: DB_DateTime, Nullable: false},
+			&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
+		},
+		Indices: []*Index{
+			&Index{Cols: []string{"account_id"}},
+			&Index{Cols: []string{"account_id", "name"}, Type: UniqueIndex},
+		},
+	}
 
-	//-------  indexes ------------------
-	mg.AddMigration("add index data_source.account_id", new(AddIndexMigration).
-		Table("data_source").Columns("account_id"))
-
-	mg.AddMigration("add unique index data_source.account_id_name", new(AddIndexMigration).
-		Table("data_source").Columns("account_id", "name").Unique())
+	mg.AddMigration("create data_source table", NewAddTableMigration(tableV1))
+	mg.AddMigration("add index data_source.account_id", NewAddIndexMigration(tableV1, tableV1.Indices[0]))
+	mg.AddMigration("add unique index data_source.account_id_name", NewAddIndexMigration(tableV1, tableV1.Indices[1]))
 
 	// ---------------------
 	// account -> org changes
 
-	//-------  drop indexes ------------------
-	mg.AddMigration("drop index data_source.account_id", new(DropIndexMigration).
-		Table("data_source").Columns("account_id"))
-
-	mg.AddMigration("drop unique index data_source.account_id_name", new(DropIndexMigration).
-		Table("data_source").Columns("account_id", "name").Unique())
-
-	//------- rename table ------------------
-	mg.AddMigration("rename table data_source to data_source_old", new(RenameTableMigration).
-		Rename("data_source", "data_source_old"))
+	// drop v1 indices
+	addDropAllIndicesMigrations(mg, "v1", tableV1)
+	// rename table
+	addTableRenameMigration(mg, "data_source", "data_source_v1", "v1")
 
-	//------- recreate table with new column names ------------------
-	mg.AddMigration("create data_source table v2", new(AddTableMigration).
-		Name("data_source").WithColumns(
-		&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
-		&Column{Name: "org_id", Type: DB_BigInt, Nullable: false},
-		&Column{Name: "version", Type: DB_Int, Nullable: false},
-		&Column{Name: "type", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "access", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "url", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "password", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "user", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "database", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "basic_auth", Type: DB_Bool, Nullable: false},
-		&Column{Name: "basic_auth_user", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "basic_auth_password", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "is_default", Type: DB_Bool, Nullable: false},
-		&Column{Name: "json_data", Type: DB_Text, Nullable: true},
-		&Column{Name: "created", Type: DB_DateTime, Nullable: false},
-		&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
-	))
+	// new table
+	var tableV2 = Table{
+		Name: "data_source",
+		Columns: []*Column{
+			&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
+			&Column{Name: "org_id", Type: DB_BigInt, Nullable: false},
+			&Column{Name: "version", Type: DB_Int, Nullable: false},
+			&Column{Name: "type", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "access", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "url", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "password", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "user", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "database", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "basic_auth", Type: DB_Bool, Nullable: false},
+			&Column{Name: "basic_auth_user", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "basic_auth_password", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "is_default", Type: DB_Bool, Nullable: false},
+			&Column{Name: "json_data", Type: DB_Text, Nullable: true},
+			&Column{Name: "created", Type: DB_DateTime, Nullable: false},
+			&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
+		},
+		Indices: []*Index{
+			&Index{Cols: []string{"org_id"}},
+			&Index{Cols: []string{"org_id", "name"}, Type: UniqueIndex},
+		},
+	}
 
-	//------- data_source table indexes ------------------
-	mg.AddMigration("add index data_source.org_id", new(AddIndexMigration).
-		Table("data_source").Columns("org_id"))
+	// create v2 table
+	mg.AddMigration("create data_source table v2", NewAddTableMigration(tableV2))
 
-	mg.AddMigration("add unique index data_source.org_id_name", new(AddIndexMigration).
-		Table("data_source").Columns("org_id", "name").Unique())
+	// add v2 indíces
+	addTableIndicesMigrations(mg, "v2", tableV2)
 
-	//------- copy data from table -------------------
-	mg.AddMigration("copy data from data_source_old table", new(CopyTableDataMigration).
-		Source("data_source_old", "id, account_id, version, type, name, access, url, password, user, database, basic_auth, basic_auth_user, basic_auth_password, is_default, created, updated").
-		Target("data_source", "id, org_id, version, type, name, access, url, password, user, database, basic_auth, basic_auth_user, basic_auth_password, is_default, created, updated"))
+	//------- copy data from v1 to v2 -------------------
+	mg.AddMigration("copy data_source v1 to v2", NewCopyTableDataMigration("data_source", "data_source_v1", map[string]string{
+		"id":                  "id",
+		"org_id":              "account_id",
+		"version":             "version",
+		"type":                "type",
+		"name":                "name",
+		"access":              "access",
+		"url":                 "password",
+		"user":                "user",
+		"database":            "database",
+		"basic_auth":          "basic_auth",
+		"basic_auth_user":     "basic_auth_user",
+		"basic_auth_password": "basic_auth_password",
+		"is_default":          "is_default",
+		"created":             "created",
+		"updated":             "updated",
+	}))
 
-	mg.AddMigration("Drop old table data_source_old", new(DropTableMigration).Table("data_source_old"))
+	mg.AddMigration("Drop old table data_source_v1", NewDropTableMigration("data_source_old"))
 }

+ 63 - 47
pkg/services/sqlstore/migrations/org_mig.go

@@ -3,53 +3,69 @@ package migrations
 import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
 
 func addOrgMigrations(mg *Migrator) {
-	//-------  org table -------------------
-	mg.AddMigration("create org table", new(AddTableMigration).
-		Name("org").WithColumns(
-		&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
-		&Column{Name: "version", Type: DB_Int, Nullable: false},
-		&Column{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "address1", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "address2", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "city", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "state", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "zip_code", Type: DB_NVarchar, Length: 50, Nullable: true},
-		&Column{Name: "country", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "billing_email", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "created", Type: DB_DateTime, Nullable: false},
-		&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
-	))
-
-	//-------  indices -------------------
-	mg.AddMigration("add unique index org.name", new(AddIndexMigration).
-		Table("org").Columns("name").Unique())
+	orgV1 := Table{
+		Name: "org",
+		Columns: []*Column{
+			&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
+			&Column{Name: "version", Type: DB_Int, Nullable: false},
+			&Column{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "address1", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "address2", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "city", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "state", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "zip_code", Type: DB_NVarchar, Length: 50, Nullable: true},
+			&Column{Name: "country", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "billing_email", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "created", Type: DB_DateTime, Nullable: false},
+			&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
+		},
+		Indices: []*Index{
+			&Index{Cols: []string{"name"}, Type: UniqueIndex},
+		},
+	}
+
+	// add org v1
+	mg.AddMigration("create org table v1", NewAddTableMigration(orgV1))
+	addTableIndicesMigrations(mg, "v1", orgV1)
+
+	orgUserV1 := Table{
+		Name: "org_user",
+		Columns: []*Column{
+			&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
+			&Column{Name: "org_id", Type: DB_BigInt},
+			&Column{Name: "user_id", Type: DB_BigInt},
+			&Column{Name: "role", Type: DB_NVarchar, Length: 20},
+			&Column{Name: "created", Type: DB_DateTime},
+			&Column{Name: "updated", Type: DB_DateTime},
+		},
+		Indices: []*Index{
+			&Index{Cols: []string{"org_id"}},
+			&Index{Cols: []string{"org_id", "user_id"}, Type: UniqueIndex},
+		},
+	}
 
 	//-------  org_user table -------------------
-	mg.AddMigration("create org_user table", new(AddTableMigration).
-		Name("org_user").WithColumns(
-		&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
-		&Column{Name: "org_id", Type: DB_BigInt},
-		&Column{Name: "user_id", Type: DB_BigInt},
-		&Column{Name: "role", Type: DB_NVarchar, Length: 20},
-		&Column{Name: "created", Type: DB_DateTime},
-		&Column{Name: "updated", Type: DB_DateTime},
-	))
-
-	//-------  indices -------------------
-	mg.AddMigration("add unique index org_user_aid_uid", new(AddIndexMigration).
-		Name("org_user_aid_uid").Table("org_user").Columns("org_id", "user_id").Unique())
-
-	//-------  TEMP table rename / copy data -------------------
-	mg.AddMigration("copy data from old account table", new(CopyTableDataMigration).
-		Source("account", "id, version, name, created, updated").
-		Target("org", "id, version, name, created, updated").
-		IfTableExists("account"))
-
-	mg.AddMigration("copy data from old account_user table", new(CopyTableDataMigration).
-		Source("account_user", "id, account_id, user_id, role, created, updated").
-		Target("org_user", "id, org_id, user_id, role, created, updated").
-		IfTableExists("account_user"))
-
-	mg.AddMigration("Drop old table account", new(DropTableMigration).Table("account"))
-	mg.AddMigration("Drop old table account_user", new(DropTableMigration).Table("account_user"))
+	mg.AddMigration("create org_user table v1", NewAddTableMigration(orgUserV1))
+	addTableIndicesMigrations(mg, "v1", orgUserV1)
+
+	//-------  copy data from old table-------------------
+	mg.AddMigration("copy data account to org", NewCopyTableDataMigration("org", "account", map[string]string{
+		"id":      "id",
+		"version": "version",
+		"name":    "name",
+		"created": "created",
+		"updated": "updated",
+	}))
+
+	mg.AddMigration("copy data account_user to org_user", NewCopyTableDataMigration("org_user", "account_user", map[string]string{
+		"id":      "id",
+		"org_id":  "account_id",
+		"user_id": "user_id",
+		"role":    "role",
+		"created": "created",
+		"updated": "updated",
+	}))
+
+	mg.AddMigration("Drop old table account", NewDropTableMigration("account"))
+	mg.AddMigration("Drop old table account_user", NewDropTableMigration("account_user"))
 }

+ 72 - 56
pkg/services/sqlstore/migrations/user_mig.go

@@ -3,22 +3,30 @@ package migrations
 import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
 
 func addUserMigrations(mg *Migrator) {
-	mg.AddMigration("create user table", new(AddTableMigration).
-		Name("user").WithColumns(
-		&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
-		&Column{Name: "version", Type: DB_Int, Nullable: false},
-		&Column{Name: "login", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "email", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "password", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "salt", Type: DB_NVarchar, Length: 50, Nullable: true},
-		&Column{Name: "rands", Type: DB_NVarchar, Length: 50, Nullable: true},
-		&Column{Name: "company", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "account_id", Type: DB_BigInt, Nullable: false},
-		&Column{Name: "is_admin", Type: DB_Bool, Nullable: false},
-		&Column{Name: "created", Type: DB_DateTime, Nullable: false},
-		&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
-	))
+	userV1 := Table{
+		Name: "user",
+		Columns: []*Column{
+			&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
+			&Column{Name: "version", Type: DB_Int, Nullable: false},
+			&Column{Name: "login", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "email", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "password", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "salt", Type: DB_NVarchar, Length: 50, Nullable: true},
+			&Column{Name: "rands", Type: DB_NVarchar, Length: 50, Nullable: true},
+			&Column{Name: "company", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "account_id", Type: DB_BigInt, Nullable: false},
+			&Column{Name: "is_admin", Type: DB_Bool, Nullable: false},
+			&Column{Name: "created", Type: DB_DateTime, Nullable: false},
+			&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
+		},
+		Indices: []*Index{
+			&Index{Cols: []string{"login"}, Type: UniqueIndex},
+			&Index{Cols: []string{"email"}, Type: UniqueIndex},
+		},
+	}
+
+	mg.AddMigration("create user table", NewAddTableMigration(userV1))
 
 	mg.AddMigration("Add email_verified flag", new(AddColumnMigration).
 		Table("user").Column(&Column{Name: "email_verified", Type: DB_Bool, Nullable: true}))
@@ -37,48 +45,56 @@ func addUserMigrations(mg *Migrator) {
 	// account -> org changes
 
 	//-------  drop indexes ------------------
-	mg.AddMigration("drop unique index user.login", new(DropIndexMigration).
-		Table("user").Columns("login").Unique())
-
-	mg.AddMigration("drop unique index user.email", new(DropIndexMigration).
-		Table("user").Columns("email").Unique())
+	addDropAllIndicesMigrations(mg, "v1", userV1)
 
 	//------- rename table ------------------
-	mg.AddMigration("rename table user to user_old", new(RenameTableMigration).
-		Rename("user", "user_old"))
+	addTableRenameMigration(mg, "user", "user_v1", "v1")
 
 	//------- recreate table with new column names ------------------
-	mg.AddMigration("create user table v2", new(AddTableMigration).
-		Name("user").WithColumns(
-		&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
-		&Column{Name: "version", Type: DB_Int, Nullable: false},
-		&Column{Name: "login", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "email", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "password", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "salt", Type: DB_NVarchar, Length: 50, Nullable: true},
-		&Column{Name: "rands", Type: DB_NVarchar, Length: 50, Nullable: true},
-		&Column{Name: "company", Type: DB_NVarchar, Length: 255, Nullable: true},
-		&Column{Name: "org_id", Type: DB_BigInt, Nullable: false},
-		&Column{Name: "email_verified", Type: DB_Bool, Nullable: true},
-		&Column{Name: "theme", Type: DB_NVarchar, Nullable: true},
-		&Column{Name: "is_admin", Type: DB_Bool, Nullable: false},
-		&Column{Name: "created", Type: DB_DateTime, Nullable: false},
-		&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
-	))
-
-	//-------  user table indexes ------------------
-	mg.AddMigration("add unique index user.login v2", new(AddIndexMigration).
-		Table("user").Columns("login").Unique())
-
-	mg.AddMigration("add unique index user.email v2", new(AddIndexMigration).
-		Table("user").Columns("email").Unique())
-
-	//------- copy data from user_old table -------------------
-	mg.AddMigration("copy data from user_old table", new(CopyTableDataMigration).
-		Source("user_old", "id, version, login, email, name, password, salt, rands, company, account_id, is_admin, created, updated").
-		Target("user", "id, version, login, email, name, password, salt, rands, company, org_id, is_admin, created, updated"))
-
-	mg.AddMigration("Drop old table user_old", new(DropTableMigration).Table("user_old"))
-
+	userV2 := Table{
+		Name: "user",
+		Columns: []*Column{
+			&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
+			&Column{Name: "version", Type: DB_Int, Nullable: false},
+			&Column{Name: "login", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "email", Type: DB_NVarchar, Length: 255, Nullable: false},
+			&Column{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "password", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "salt", Type: DB_NVarchar, Length: 50, Nullable: true},
+			&Column{Name: "rands", Type: DB_NVarchar, Length: 50, Nullable: true},
+			&Column{Name: "company", Type: DB_NVarchar, Length: 255, Nullable: true},
+			&Column{Name: "org_id", Type: DB_BigInt, Nullable: false},
+			&Column{Name: "is_admin", Type: DB_Bool, Nullable: false},
+			&Column{Name: "email_verified", Type: DB_Bool, Nullable: true},
+			&Column{Name: "theme", Type: DB_NVarchar, Nullable: true},
+			&Column{Name: "created", Type: DB_DateTime, Nullable: false},
+			&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
+		},
+		Indices: []*Index{
+			&Index{Cols: []string{"login"}, Type: UniqueIndex},
+			&Index{Cols: []string{"email"}, Type: UniqueIndex},
+		},
+	}
+
+	mg.AddMigration("create user table v2", NewAddTableMigration(userV2))
+	addTableIndicesMigrations(mg, "v2", userV2)
+
+	//------- copy data from v1 to v2 -------------------
+	mg.AddMigration("copy data_source v1 to v2", NewCopyTableDataMigration("user", "user_v1", map[string]string{
+		"id":       "id",
+		"version":  "version",
+		"login":    "login",
+		"email":    "email",
+		"name":     "name",
+		"password": "password",
+		"salt":     "salt",
+		"rands":    "rands",
+		"company":  "company",
+		"org_id":   "account_id",
+		"is_admin": "is_admin",
+		"created":  "created",
+		"updated":  "updated",
+	}))
+
+	mg.AddMigration("Drop old table user_v1", NewDropTableMigration("user_v1"))
 }

+ 17 - 7
pkg/services/sqlstore/migrator/dialect.go

@@ -20,7 +20,7 @@ type Dialect interface {
 	CreateIndexSql(tableName string, index *Index) string
 	CreateTableSql(table *Table) string
 	AddColumnSql(tableName string, Col *Column) string
-	CopyTableData(sourceTable string, targetTable string, sourceCols string, targetCols string) string
+	CopyTableData(sourceTable string, targetTable string, sourceCols []string, targetCols []string) string
 	DropTable(tableName string) string
 	DropIndexSql(tableName string, index *Index) string
 
@@ -105,22 +105,32 @@ func (db *BaseDialect) AddColumnSql(tableName string, col *Column) string {
 func (db *BaseDialect) CreateIndexSql(tableName string, index *Index) string {
 	quote := db.dialect.Quote
 	var unique string
-	var idxName string
 	if index.Type == UniqueIndex {
 		unique = " UNIQUE"
-		idxName = fmt.Sprintf("UQE_%v_%v", tableName, index.Name)
-	} else {
-		idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name)
 	}
 
+	idxName := index.XName(tableName)
+
 	return fmt.Sprintf("CREATE%s INDEX %v ON %v (%v);", unique,
 		quote(idxName), quote(tableName),
 		quote(strings.Join(index.Cols, quote(","))))
 }
 
-func (db *BaseDialect) CopyTableData(sourceTable string, targetTable string, sourceCols string, targetCols string) string {
+func (db *BaseDialect) QuoteColList(cols []string) string {
+	var sourceColsSql = ""
+	for _, col := range cols {
+		sourceColsSql += db.dialect.Quote(col)
+		sourceColsSql += "\n, "
+	}
+	return strings.TrimSuffix(sourceColsSql, "\n, ")
+}
+
+func (db *BaseDialect) CopyTableData(sourceTable string, targetTable string, sourceCols []string, targetCols []string) string {
+	sourceColsSql := db.QuoteColList(sourceCols)
+	targetColsSql := db.QuoteColList(targetCols)
+
 	quote := db.dialect.Quote
-	return fmt.Sprintf("INSERT INTO %s (%s) SELECT %s FROM %s", quote(targetTable), targetCols, sourceCols, quote(sourceTable))
+	return fmt.Sprintf("INSERT INTO %s (%s) SELECT %s FROM %s", quote(targetTable), targetColsSql, sourceColsSql, quote(sourceTable))
 }
 
 func (db *BaseDialect) DropTable(tableName string) string {

+ 34 - 27
pkg/services/sqlstore/migrator/migrations.go

@@ -73,12 +73,11 @@ func (m *AddColumnMigration) Sql(dialect Dialect) string {
 type AddIndexMigration struct {
 	MigrationBase
 	tableName string
-	index     Index
+	index     *Index
 }
 
-func (m *AddIndexMigration) Name(name string) *AddIndexMigration {
-	m.index.Name = name
-	return m
+func NewAddIndexMigration(table Table, index *Index) *AddIndexMigration {
+	return &AddIndexMigration{tableName: table.Name, index: index}
 }
 
 func (m *AddIndexMigration) Table(tableName string) *AddIndexMigration {
@@ -92,26 +91,23 @@ func (m *AddIndexMigration) Unique() *AddIndexMigration {
 }
 
 func (m *AddIndexMigration) Columns(columns ...string) *AddIndexMigration {
+	m.index = &Index{}
 	m.index.Cols = columns
 	return m
 }
 
 func (m *AddIndexMigration) Sql(dialect Dialect) string {
-	if m.index.Name == "" {
-		m.index.Name = fmt.Sprintf("%s", strings.Join(m.index.Cols, "_"))
-	}
-	return dialect.CreateIndexSql(m.tableName, &m.index)
+	return dialect.CreateIndexSql(m.tableName, m.index)
 }
 
 type DropIndexMigration struct {
 	MigrationBase
 	tableName string
-	index     Index
+	index     *Index
 }
 
-func (m *DropIndexMigration) Name(name string) *DropIndexMigration {
-	m.index.Name = name
-	return m
+func NewDropIndexMigration(table Table, index *Index) *DropIndexMigration {
+	return &DropIndexMigration{tableName: table.Name, index: index}
 }
 
 func (m *DropIndexMigration) Table(tableName string) *DropIndexMigration {
@@ -125,6 +121,7 @@ func (m *DropIndexMigration) Unique() *DropIndexMigration {
 }
 
 func (m *DropIndexMigration) Columns(columns ...string) *DropIndexMigration {
+	m.index = &Index{}
 	m.index.Cols = columns
 	return m
 }
@@ -133,7 +130,7 @@ func (m *DropIndexMigration) Sql(dialect Dialect) string {
 	if m.index.Name == "" {
 		m.index.Name = fmt.Sprintf("%s", strings.Join(m.index.Cols, "_"))
 	}
-	return dialect.DropIndexSql(m.tableName, &m.index)
+	return dialect.DropIndexSql(m.tableName, m.index)
 }
 
 type AddTableMigration struct {
@@ -141,10 +138,19 @@ type AddTableMigration struct {
 	table Table
 }
 
+func NewAddTableMigration(table Table) *AddTableMigration {
+	return &AddTableMigration{table: table}
+}
+
 func (m *AddTableMigration) Sql(d Dialect) string {
 	return d.CreateTableSql(&m.table)
 }
 
+func (m *AddTableMigration) Table(table Table) *AddTableMigration {
+	m.table = table
+	return m
+}
+
 func (m *AddTableMigration) Name(name string) *AddTableMigration {
 	m.table.Name = name
 	return m
@@ -173,9 +179,8 @@ type DropTableMigration struct {
 	tableName string
 }
 
-func (m *DropTableMigration) Table(tableName string) *DropTableMigration {
-	m.tableName = tableName
-	return m
+func NewDropTableMigration(tableName string) *DropTableMigration {
+	return &DropTableMigration{tableName: tableName}
 }
 
 func (m *DropTableMigration) Sql(d Dialect) string {
@@ -188,6 +193,10 @@ type RenameTableMigration struct {
 	newName string
 }
 
+func NewRenameTableMigration(oldName string, newName string) *RenameTableMigration {
+	return &RenameTableMigration{oldName: oldName, newName: newName}
+}
+
 func (m *RenameTableMigration) IfTableExists(tableName string) *RenameTableMigration {
 	m.Condition = &IfTableExistsCondition{TableName: tableName}
 	return m
@@ -207,19 +216,17 @@ type CopyTableDataMigration struct {
 	MigrationBase
 	sourceTable string
 	targetTable string
-	sourceCols  string
-	targetCols  string
+	sourceCols  []string
+	targetCols  []string
+	colMap      map[string]string
 }
 
-func (m *CopyTableDataMigration) Source(tableName string, cols string) *CopyTableDataMigration {
-	m.sourceTable = tableName
-	m.sourceCols = cols
-	return m
-}
-
-func (m *CopyTableDataMigration) Target(tableName string, cols string) *CopyTableDataMigration {
-	m.targetTable = tableName
-	m.targetCols = cols
+func NewCopyTableDataMigration(targetTable string, sourceTable string, colMap map[string]string) *CopyTableDataMigration {
+	m := &CopyTableDataMigration{sourceTable: sourceTable, targetTable: targetTable}
+	for key, value := range colMap {
+		m.targetCols = append(m.targetCols, key)
+		m.sourceCols = append(m.sourceCols, value)
+	}
 	return m
 }
 

+ 5 - 0
pkg/services/sqlstore/migrator/types.go

@@ -30,6 +30,7 @@ type Table struct {
 	Name        string
 	Columns     []*Column
 	PrimaryKeys []string
+	Indices     []*Index
 }
 
 const (
@@ -44,6 +45,10 @@ type Index struct {
 }
 
 func (index *Index) XName(tableName string) string {
+	if index.Name == "" {
+		index.Name = fmt.Sprintf("%s", strings.Join(index.Cols, "_"))
+	}
+
 	if !strings.HasPrefix(index.Name, "UQE_") &&
 		!strings.HasPrefix(index.Name, "IDX_") {
 		if index.Type == UniqueIndex {