Nested folders: Fetch multiple folders from dashboard folder store (#72464)
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user