grafana/pkg/services/search/service.go
Ezequiel Victorero 42d75ac737
Dashboards: Add feature restore dashboards backend (#83131)
Co-authored-by: Sofia Papagiannaki <1632407+papagian@users.noreply.github.com>
2024-05-16 14:36:26 -03:00

145 lines
3.7 KiB
Go

package search
import (
"context"
"sort"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/dashboards/dashboardaccess"
"github.com/grafana/grafana/pkg/services/search/model"
"github.com/grafana/grafana/pkg/services/star"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
func ProvideService(cfg *setting.Cfg, sqlstore db.DB, starService star.Service, dashboardService dashboards.DashboardService) *SearchService {
s := &SearchService{
Cfg: cfg,
sortOptions: map[string]model.SortOption{
SortAlphaAsc.Name: SortAlphaAsc,
SortAlphaDesc.Name: SortAlphaDesc,
},
sqlstore: sqlstore,
starService: starService,
dashboardService: dashboardService,
}
return s
}
type Query struct {
Title string
Tags []string
OrgId int64
SignedInUser *user.SignedInUser
Limit int64
Page int64
IsStarred bool
IsDeleted bool
Type string
DashboardUIDs []string
DashboardIds []int64
// Deprecated: use FolderUID instead
FolderIds []int64
FolderUIDs []string
Permission dashboardaccess.PermissionType
Sort string
}
type Service interface {
SearchHandler(context.Context, *Query) (model.HitList, error)
SortOptions() []model.SortOption
}
type SearchService struct {
Cfg *setting.Cfg
sortOptions map[string]model.SortOption
sqlstore db.DB
starService star.Service
dashboardService dashboards.DashboardService
}
func (s *SearchService) SearchHandler(ctx context.Context, query *Query) (model.HitList, error) {
starredQuery := star.GetUserStarsQuery{
UserID: query.SignedInUser.UserID,
}
staredDashIDs, err := s.starService.GetByUser(ctx, &starredQuery)
if err != nil {
return nil, err
}
// No starred dashboards will be found
if query.IsStarred && len(staredDashIDs.UserStars) == 0 {
return model.HitList{}, nil
}
// filter by starred dashboard IDs when starred dashboards are requested and no UID or ID filters are specified to improve query performance
if query.IsStarred && len(query.DashboardIds) == 0 && len(query.DashboardUIDs) == 0 {
for id := range staredDashIDs.UserStars {
query.DashboardIds = append(query.DashboardIds, id)
}
}
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Search).Inc()
dashboardQuery := dashboards.FindPersistedDashboardsQuery{
Title: query.Title,
SignedInUser: query.SignedInUser,
DashboardUIDs: query.DashboardUIDs,
DashboardIds: query.DashboardIds,
Type: query.Type,
FolderIds: query.FolderIds, // nolint:staticcheck
FolderUIDs: query.FolderUIDs,
Tags: query.Tags,
Limit: query.Limit,
Page: query.Page,
Permission: query.Permission,
IsDeleted: query.IsDeleted,
}
if sortOpt, exists := s.sortOptions[query.Sort]; exists {
dashboardQuery.Sort = sortOpt
}
hits, err := s.dashboardService.SearchDashboards(ctx, &dashboardQuery)
if err != nil {
return nil, err
}
if query.Sort == "" {
hits = sortedHits(hits)
}
// set starred dashboards
for _, dashboard := range hits {
if _, ok := staredDashIDs.UserStars[dashboard.ID]; ok {
dashboard.IsStarred = true
}
}
// filter for starred dashboards if requested
if !query.IsStarred {
return hits, nil
}
result := model.HitList{}
for _, dashboard := range hits {
if dashboard.IsStarred {
result = append(result, dashboard)
}
}
return result, nil
}
func sortedHits(unsorted model.HitList) model.HitList {
hits := make(model.HitList, 0)
hits = append(hits, unsorted...)
sort.Sort(hits)
for _, hit := range hits {
sort.Strings(hit.Tags)
}
return hits
}