Dashboards: Remove unique name constraints (#90687)
This commit is contained in:
@@ -84,12 +84,6 @@ func (d *dashboardStore) ValidateDashboardBeforeSave(ctx context.Context, dashbo
|
||||
return err
|
||||
}
|
||||
|
||||
isParentFolderChanged, err = getExistingDashboardByTitleAndFolder(sess, dashboard, overwrite,
|
||||
isParentFolderChanged)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -353,49 +347,6 @@ func getExistingDashboardByIDOrUIDForUpdate(sess *db.Session, dash *dashboards.D
|
||||
return isParentFolderChanged, nil
|
||||
}
|
||||
|
||||
// getExistingDashboardByTitleAndFolder returns a boolean (on whether the parent folder changed) and an error for if the dashboard already exists.
|
||||
func getExistingDashboardByTitleAndFolder(sess *db.Session, dash *dashboards.Dashboard, overwrite,
|
||||
isParentFolderChanged bool) (bool, error) {
|
||||
var existing dashboards.Dashboard
|
||||
condition := "org_id=? AND title=?"
|
||||
args := []any{dash.OrgID, dash.Title}
|
||||
if dash.FolderUID != "" {
|
||||
condition += " AND folder_uid=?"
|
||||
args = append(args, dash.FolderUID)
|
||||
} else {
|
||||
condition += " AND folder_uid IS NULL"
|
||||
}
|
||||
exists, err := sess.Where(condition, args...).Get(&existing)
|
||||
if err != nil {
|
||||
return isParentFolderChanged, fmt.Errorf("SQL query for existing dashboard by org ID or folder ID failed: %w", err)
|
||||
}
|
||||
if exists && dash.ID != existing.ID {
|
||||
if existing.IsFolder && !dash.IsFolder {
|
||||
return isParentFolderChanged, dashboards.ErrDashboardWithSameNameAsFolder
|
||||
}
|
||||
|
||||
if !existing.IsFolder && dash.IsFolder {
|
||||
return isParentFolderChanged, dashboards.ErrDashboardFolderWithSameNameAsDashboard
|
||||
}
|
||||
|
||||
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Dashboard).Inc()
|
||||
// nolint:staticcheck
|
||||
if !dash.IsFolder && (dash.FolderID != existing.FolderID || dash.ID == 0) {
|
||||
isParentFolderChanged = true
|
||||
}
|
||||
|
||||
if overwrite {
|
||||
dash.SetID(existing.ID)
|
||||
dash.SetUID(existing.UID)
|
||||
dash.SetVersion(existing.Version)
|
||||
} else {
|
||||
return isParentFolderChanged, dashboards.ErrDashboardWithSameNameInFolderExists
|
||||
}
|
||||
}
|
||||
|
||||
return isParentFolderChanged, nil
|
||||
}
|
||||
|
||||
func saveDashboard(sess *db.Session, cmd *dashboards.SaveDashboardCommand, emitEntityEvent bool) (*dashboards.Dashboard, error) {
|
||||
dash := cmd.GetDashboardModel()
|
||||
|
||||
@@ -797,8 +748,8 @@ func (d *dashboardStore) GetDashboard(ctx context.Context, query *dashboards.Get
|
||||
|
||||
dashboard := dashboards.Dashboard{OrgID: query.OrgID, ID: query.ID, UID: query.UID}
|
||||
mustCols := []string{}
|
||||
if query.Title != nil {
|
||||
dashboard.Title = *query.Title
|
||||
if query.Title != nil { // nolint:staticcheck
|
||||
dashboard.Title = *query.Title // nolint:staticcheck
|
||||
mustCols = append(mustCols, "title")
|
||||
}
|
||||
|
||||
@@ -806,8 +757,7 @@ func (d *dashboardStore) GetDashboard(ctx context.Context, query *dashboards.Get
|
||||
dashboard.FolderUID = *query.FolderUID
|
||||
mustCols = append(mustCols, "folder_uid")
|
||||
} else if query.FolderID != nil { // nolint:staticcheck
|
||||
// nolint:staticcheck
|
||||
dashboard.FolderID = *query.FolderID
|
||||
dashboard.FolderID = *query.FolderID // nolint:staticcheck
|
||||
mustCols = append(mustCols, "folder_id")
|
||||
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Dashboard).Inc()
|
||||
}
|
||||
|
||||
@@ -781,40 +781,6 @@ func TestIntegrationDashboard_Filter(t *testing.T) {
|
||||
assert.Equal(t, dashB.ID, results[0].ID)
|
||||
}
|
||||
|
||||
func TestGetExistingDashboardByTitleAndFolder(t *testing.T) {
|
||||
sqlStore := db.InitTestDB(t)
|
||||
cfg := setting.NewCfg()
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dashboardStore, err := ProvideDashboardStore(sqlStore, cfg, testFeatureToggles, tagimpl.ProvideService(sqlStore), quotaService)
|
||||
require.NoError(t, err)
|
||||
insertTestDashboard(t, dashboardStore, "Apple", 1, 0, "", false)
|
||||
t.Run("Finds a dashboard with existing name in root directory and throws DashboardWithSameNameInFolderExists error", func(t *testing.T) {
|
||||
err = sqlStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
_, err = getExistingDashboardByTitleAndFolder(sess, &dashboards.Dashboard{Title: "Apple", OrgID: 1}, false, false)
|
||||
return err
|
||||
})
|
||||
require.ErrorIs(t, err, dashboards.ErrDashboardWithSameNameInFolderExists)
|
||||
})
|
||||
|
||||
t.Run("Returns no error when dashboard does not exist in root folder", func(t *testing.T) {
|
||||
err = sqlStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
_, err = getExistingDashboardByTitleAndFolder(sess, &dashboards.Dashboard{Title: "Beta", OrgID: 1}, false, false)
|
||||
return err
|
||||
})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Finds a dashboard with existing name in specific folder and throws DashboardWithSameNameInFolderExists error", func(t *testing.T) {
|
||||
savedFolder := insertTestDashboard(t, dashboardStore, "test dash folder", 1, 0, "", true, "prod", "webapp")
|
||||
savedDash := insertTestDashboard(t, dashboardStore, "test dash", 1, savedFolder.ID, savedFolder.UID, false, "prod", "webapp")
|
||||
err = sqlStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
_, err = getExistingDashboardByTitleAndFolder(sess, &dashboards.Dashboard{Title: savedDash.Title, FolderUID: savedFolder.UID, OrgID: 1}, false, false)
|
||||
return err
|
||||
})
|
||||
require.ErrorIs(t, err, dashboards.ErrDashboardWithSameNameInFolderExists)
|
||||
})
|
||||
}
|
||||
|
||||
func TestIntegrationFindDashboardsByTitle(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test")
|
||||
|
||||
@@ -98,6 +98,7 @@ func AddDashboardFolderMigrations(mg *migrator.Migrator) {
|
||||
|
||||
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,
|
||||
}))
|
||||
@@ -106,4 +107,8 @@ func AddDashboardFolderMigrations(mg *migrator.Migrator) {
|
||||
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,
|
||||
}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user