Nested folders: Fetch multiple folders from dashboard folder store (#72464)

This commit is contained in:
Sofia Papagiannaki
2023-08-01 11:04:44 +03:00
committed by GitHub
parent 7612f3d955
commit 1869da1d86
5 changed files with 102 additions and 14 deletions
@@ -2,6 +2,7 @@ package folderimpl
import (
"context"
"strings"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/services/dashboards"
@@ -84,3 +85,38 @@ func (d *DashboardFolderStoreImpl) GetFolderByUID(ctx context.Context, orgID int
}
return dashboards.FromDashboard(&dashboard), nil
}
func (d *DashboardFolderStoreImpl) GetFolders(ctx context.Context, orgID int64, uids []string) (map[string]*folder.Folder, error) {
m := make(map[string]*folder.Folder, len(uids))
var folders []*folder.Folder
if err := d.store.WithDbSession(ctx, func(sess *db.Session) error {
b := strings.Builder{}
args := make([]interface{}, 0, len(uids)+1)
b.WriteString("SELECT * FROM dashboard WHERE org_id=? ")
args = append(args, orgID)
for i, uid := range uids {
if i == 0 {
b.WriteString(" AND (")
}
if i > 0 {
b.WriteString(" OR ")
}
b.WriteString(" uid=? ")
args = append(args, uid)
if i == len(uids)-1 {
b.WriteString(")")
}
}
return sess.SQL(b.String(), args...).Find(&folders)
}); err != nil {
return nil, err
}
for _, f := range folders {
m[f.UID] = f
}
return m, nil
}
+21 -5
View File
@@ -184,14 +184,25 @@ func (s *Service) GetChildren(ctx context.Context, cmd *folder.GetChildrenQuery)
return nil, err
}
childrenUIDs := make([]string, 0, len(children))
for _, f := range children {
childrenUIDs = append(childrenUIDs, f.UID)
}
dashFolders, err := s.dashboardFolderStore.GetFolders(ctx, cmd.OrgID, childrenUIDs)
if err != nil {
return nil, folder.ErrInternal.Errorf("failed to fetch subfolders from dashboard store: %w", err)
}
filtered := make([]*folder.Folder, 0, len(children))
for _, f := range children {
// fetch folder from dashboard store
dashFolder, err := s.dashboardFolderStore.GetFolderByUID(ctx, f.OrgID, f.UID)
if err != nil {
s.log.Error("failed to fetch folder by UID from dashboard store", "uid", f.UID, "error", err)
dashFolder, ok := dashFolders[f.UID]
if !ok {
s.log.Error("failed to fetch folder by UID from dashboard store", "uid", f.UID)
continue
}
// always expose the dashboard store sequential ID
f.ID = dashFolder.ID
@@ -500,9 +511,14 @@ func (s *Service) Delete(ctx context.Context, cmd *folder.DeleteFolderCommand) e
result = append(result, subfolders...)
}
dashFolders, err := s.dashboardFolderStore.GetFolders(ctx, cmd.OrgID, result)
if err != nil {
return folder.ErrInternal.Errorf("failed to fetch subfolders from dashboard store: %w", err)
}
for _, folder := range result {
dashFolder, err := s.dashboardFolderStore.GetFolderByUID(ctx, cmd.OrgID, folder)
if err != nil {
dashFolder, ok := dashFolders[folder]
if !ok {
return err
}
@@ -240,7 +240,7 @@ func TestIntegrationFolderService(t *testing.T) {
f := folder.NewFolder(util.GenerateShortUID(), "")
f.ID = rand.Int63()
f.UID = util.GenerateShortUID()
folderStore.On("GetFolderByUID", mock.Anything, orgID, f.UID).Return(f, nil)
folderStore.On("GetFolders", mock.Anything, orgID, []string{f.UID}).Return(map[string]*folder.Folder{f.UID: f}, nil)
var actualCmd *dashboards.DeleteDashboardCommand
dashStore.On("DeleteDashboard", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {