The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/services/dashboards/database/migrations/folder_uid_migrator.go

114 lines
4.1 KiB

package migrations
import (
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"xorm.io/xorm"
)
type DummyMigration struct {
migrator.MigrationBase
}
func (m *DummyMigration) SQL(dialect migrator.Dialect) string {
return "code migration"
}
func (m *DummyMigration) Exec(sess *xorm.Session, mgrtr *migrator.Migrator) error {
return nil
}
// FolderUIDMigration is a code migration that populates folder_uid column
type FolderUIDMigration struct {
migrator.MigrationBase
}
func (m *FolderUIDMigration) SQL(dialect migrator.Dialect) string {
return "code migration"
}
func (m *FolderUIDMigration) Exec(sess *xorm.Session, mgrtr *migrator.Migrator) error {
// for dashboards the source of truth is the dashboard table
q := `UPDATE dashboard
SET folder_uid = folder.uid
FROM dashboard folder
WHERE dashboard.folder_id = folder.id
AND dashboard.is_folder = ?`
if mgrtr.Dialect.DriverName() == migrator.MySQL {
q = `UPDATE dashboard AS d
LEFT JOIN dashboard AS folder ON d.folder_id = folder.id
SET d.folder_uid = folder.uid
WHERE d.is_folder = ?`
}
r, err := sess.Exec(q, mgrtr.Dialect.BooleanValue(false))
if err != nil {
mgrtr.Logger.Error("Failed to migrate dashboard folder_uid for dashboards", "error", err)
return err
}
dashboardRowsAffected, dashboardRowsAffectedErr := r.RowsAffected()
if dashboardRowsAffectedErr != nil {
mgrtr.Logger.Error("Failed to get dashboard rows affected", "error", dashboardRowsAffectedErr)
}
// for folders the source of truth is the folder table
// covered by UQE_folder_org_id_uid
q = `UPDATE dashboard
SET folder_uid = folder.parent_uid
FROM folder
WHERE dashboard.uid = folder.uid AND dashboard.org_id = folder.org_id
AND dashboard.is_folder = ?`
// covered by UQE_folder_org_id_uid
if mgrtr.Dialect.DriverName() == migrator.MySQL {
q = `UPDATE dashboard
SET folder_uid = (
SELECT folder.parent_uid
FROM folder
WHERE dashboard.uid = folder.uid AND dashboard.org_id = folder.org_id
)
WHERE is_folder = ?`
}
r, err = sess.Exec(q, mgrtr.Dialect.BooleanValue(true))
if err != nil {
mgrtr.Logger.Error("Failed to migrate dashboard folder_uid for folders", "error", err)
return err
}
folderRowsAffected, folderRowsAffectedErr := r.RowsAffected()
if folderRowsAffectedErr != nil {
mgrtr.Logger.Error("Failed to get folder rows affected", "error", folderRowsAffectedErr)
}
mgrtr.Logger.Debug("Migrating dashboard data", "dashboards rows", dashboardRowsAffected, "folder rows", folderRowsAffected)
return nil
}
func AddDashboardFolderMigrations(mg *migrator.Migrator) {
mg.AddMigration("Add folder_uid for dashboard", migrator.NewAddColumnMigration(migrator.Table{Name: "dashboard"}, &migrator.Column{
Name: "folder_uid", Type: migrator.DB_NVarchar, Length: 40, Nullable: true,
}))
mg.AddMigration("Populate dashboard folder_uid column", &FolderUIDMigration{})
mg.AddMigration("Add unique index for dashboard_org_id_folder_uid_title", &DummyMigration{})
mg.AddMigration("Delete unique index for dashboard_org_id_folder_id_title", migrator.NewDropIndexMigration(migrator.Table{Name: "dashboard"}, &migrator.Index{
Cols: []string{"org_id", "folder_id", "title"}, Type: migrator.UniqueIndex,
}))
mg.AddMigration("Delete unique index for dashboard_org_id_folder_uid_title", &DummyMigration{})
// Removed a few lines below
mg.AddMigration("Add unique index for dashboard_org_id_folder_uid_title_is_folder", migrator.NewAddIndexMigration(migrator.Table{Name: "dashboard"}, &migrator.Index{
Cols: []string{"org_id", "folder_uid", "title", "is_folder"}, Type: migrator.UniqueIndex,
}))
// Temporary index until decommisioning of folder_id in query
mg.AddMigration("Restore index for dashboard_org_id_folder_id_title", migrator.NewAddIndexMigration(migrator.Table{Name: "dashboard"}, &migrator.Index{
Cols: []string{"org_id", "folder_id", "title"},
}))
mg.AddMigration("Remove unique index for dashboard_org_id_folder_uid_title_is_folder", migrator.NewDropIndexMigration(migrator.Table{Name: "dashboard"}, &migrator.Index{
Cols: []string{"org_id", "folder_uid", "title", "is_folder"}, Type: migrator.UniqueIndex,
}))
}