diff --git a/pkg/services/sqlstore/migrations/apikey_mig.go b/pkg/services/sqlstore/migrations/apikey_mig.go index 746009b219b..1b2dc433941 100644 --- a/pkg/services/sqlstore/migrations/apikey_mig.go +++ b/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}, - )) + 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}, + }, + } - //------- 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()) + // 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")) + // drop indexes + addDropAllIndicesMigrations(mg, "v1", apiKeyV1) + // rename table + addTableRenameMigration(mg, "api_key", "api_key_v1", "v1") - mg.AddMigration("drop index api_key.key", new(DropIndexMigration). - Table("api_key").Columns("key").Unique()) + 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}, + }, + } - mg.AddMigration("drop index api_key.account_id_name", new(DropIndexMigration). - Table("api_key").Columns("account_id", "name").Unique()) + // create v2 table + mg.AddMigration("create api_key table v2", NewAddTableMigration(apiKeyV2)) - //------- rename table ------------------ - mg.AddMigration("rename table api_key to api_key_old", new(RenameTableMigration). - Rename("api_key", "api_key_old")) + // add v2 indíces + addTableIndicesMigrations(mg, "v2", apiKeyV2) - //------- 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}, - )) + //------- 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", + })) - //------- 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")) + mg.AddMigration("Drop old table api_key_v1", NewDropTableMigration("api_key_v1")) } diff --git a/pkg/services/sqlstore/migrations/common.go b/pkg/services/sqlstore/migrations/common.go new file mode 100644 index 00000000000..68089aab143 --- /dev/null +++ b/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)) +} diff --git a/pkg/services/sqlstore/migrations/dashboard_mig.go b/pkg/services/sqlstore/migrations/dashboard_mig.go index 551084934d1..d1579a8da2a 100644 --- a/pkg/services/sqlstore/migrations/dashboard_mig.go +++ b/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}, - )) + 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_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}, - )) + 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 index dashboard.account_id", NewAddIndexMigration(dashboardV1, dashboardV1.Indices[0])) + mg.AddMigration("add unique index dashboard_account_id_slug", NewAddIndexMigration(dashboardV1, dashboardV1.Indices[1])) - mg.AddMigration("add unique index dashboard_account_id_slug", new(AddIndexMigration). - Table("dashboard").Columns("account_id", "slug").Unique()) + 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("add unique index dashboard_tag.dasboard_id_term", new(AddIndexMigration). - Table("dashboard_tag").Columns("dashboard_id", "term").Unique()) + 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")) + addTableRenameMigration(mg, "dashboard", "dashboard_v1", "v1") - //------- 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 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}, + }, + } - //------- dashboard table indexes ------------------ - mg.AddMigration("add index dashboard.org_id", new(AddIndexMigration). - Table("dashboard").Columns("org_id")) + // 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("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")) + mg.AddMigration("drop table dashboard_v1", NewDropTableMigration("dashboard_v1")) } diff --git a/pkg/services/sqlstore/migrations/datasource_mig.go b/pkg/services/sqlstore/migrations/datasource_mig.go index 8f8a77dae7f..64ab496298d 100644 --- a/pkg/services/sqlstore/migrations/datasource_mig.go +++ b/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")) + // drop v1 indices + addDropAllIndicesMigrations(mg, "v1", tableV1) + // rename table + addTableRenameMigration(mg, "data_source", "data_source_v1", "v1") - mg.AddMigration("drop unique index data_source.account_id_name", new(DropIndexMigration). - Table("data_source").Columns("account_id", "name").Unique()) + // 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}, + }, + } - //------- rename table ------------------ - mg.AddMigration("rename table data_source to data_source_old", new(RenameTableMigration). - Rename("data_source", "data_source_old")) + // create v2 table + mg.AddMigration("create data_source table v2", NewAddTableMigration(tableV2)) - //------- 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}, - )) + // add v2 indíces + addTableIndicesMigrations(mg, "v2", tableV2) - //------- data_source table indexes ------------------ - mg.AddMigration("add index data_source.org_id", new(AddIndexMigration). - Table("data_source").Columns("org_id")) + //------- 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("add unique index data_source.org_id_name", new(AddIndexMigration). - Table("data_source").Columns("org_id", "name").Unique()) - - //------- 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")) - - 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")) } diff --git a/pkg/services/sqlstore/migrations/org_mig.go b/pkg/services/sqlstore/migrations/org_mig.go index d07ac3d0dec..f46b3696aa7 100644 --- a/pkg/services/sqlstore/migrations/org_mig.go +++ b/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}, - )) + 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}, + }, + } - //------- indices ------------------- - mg.AddMigration("add unique index org.name", new(AddIndexMigration). - Table("org").Columns("name").Unique()) + // 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}, - )) + mg.AddMigration("create org_user table v1", NewAddTableMigration(orgUserV1)) + addTableIndicesMigrations(mg, "v1", orgUserV1) - //------- 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()) + //------- 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", + })) - //------- 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 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("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("Drop old table account", NewDropTableMigration("account")) + mg.AddMigration("Drop old table account_user", NewDropTableMigration("account_user")) } diff --git a/pkg/services/sqlstore/migrations/user_mig.go b/pkg/services/sqlstore/migrations/user_mig.go index 8f41a336b66..267a23e2104 100644 --- a/pkg/services/sqlstore/migrations/user_mig.go +++ b/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}, - )) + 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}, + }, + } - //------- user table indexes ------------------ - mg.AddMigration("add unique index user.login v2", new(AddIndexMigration). - Table("user").Columns("login").Unique()) + mg.AddMigration("create user table v2", NewAddTableMigration(userV2)) + addTableIndicesMigrations(mg, "v2", userV2) - 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")) + //------- 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")) } diff --git a/pkg/services/sqlstore/migrator/dialect.go b/pkg/services/sqlstore/migrator/dialect.go index 3e83257ac7d..9e3c3a11e16 100644 --- a/pkg/services/sqlstore/migrator/dialect.go +++ b/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 { diff --git a/pkg/services/sqlstore/migrator/migrations.go b/pkg/services/sqlstore/migrator/migrations.go index 0f34c0a11dd..be357fed8bc 100644 --- a/pkg/services/sqlstore/migrator/migrations.go +++ b/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 } diff --git a/pkg/services/sqlstore/migrator/types.go b/pkg/services/sqlstore/migrator/types.go index 7af0764435a..d42eba0f58a 100644 --- a/pkg/services/sqlstore/migrator/types.go +++ b/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 {