2019-10-11 10:08:15 -05:00
|
|
|
package search
|
|
|
|
|
|
|
|
import (
|
2021-10-27 08:57:06 -05:00
|
|
|
"context"
|
2020-04-27 07:16:03 -05:00
|
|
|
"sort"
|
|
|
|
|
2022-10-19 08:02:15 -05:00
|
|
|
"github.com/grafana/grafana/pkg/infra/db"
|
2024-01-25 04:10:35 -06:00
|
|
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
2022-05-24 08:24:55 -05:00
|
|
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
2023-11-22 07:20:22 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/dashboards/dashboardaccess"
|
2023-01-30 08:17:53 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/search/model"
|
2022-05-19 07:32:10 -05:00
|
|
|
"github.com/grafana/grafana/pkg/services/star"
|
2022-08-10 04:56:48 -05:00
|
|
|
"github.com/grafana/grafana/pkg/services/user"
|
2020-04-20 09:20:45 -05:00
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
2019-10-11 10:08:15 -05:00
|
|
|
)
|
|
|
|
|
2022-10-14 14:33:06 -05:00
|
|
|
func ProvideService(cfg *setting.Cfg, sqlstore db.DB, starService star.Service, dashboardService dashboards.DashboardService) *SearchService {
|
2021-08-25 08:11:22 -05:00
|
|
|
s := &SearchService{
|
|
|
|
Cfg: cfg,
|
2023-01-30 08:17:53 -06:00
|
|
|
sortOptions: map[string]model.SortOption{
|
2021-08-25 08:11:22 -05:00
|
|
|
SortAlphaAsc.Name: SortAlphaAsc,
|
|
|
|
SortAlphaDesc.Name: SortAlphaDesc,
|
|
|
|
},
|
2022-05-24 08:24:55 -05:00
|
|
|
sqlstore: sqlstore,
|
|
|
|
starService: starService,
|
|
|
|
dashboardService: dashboardService,
|
2021-08-25 08:11:22 -05:00
|
|
|
}
|
|
|
|
return s
|
2019-10-11 10:08:15 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
type Query struct {
|
2022-06-02 14:56:01 -05:00
|
|
|
Title string
|
|
|
|
Tags []string
|
|
|
|
OrgId int64
|
2022-08-10 04:56:48 -05:00
|
|
|
SignedInUser *user.SignedInUser
|
2022-06-02 14:56:01 -05:00
|
|
|
Limit int64
|
|
|
|
Page int64
|
|
|
|
IsStarred bool
|
2024-05-16 12:36:26 -05:00
|
|
|
IsDeleted bool
|
2022-06-02 14:56:01 -05:00
|
|
|
Type string
|
|
|
|
DashboardUIDs []string
|
|
|
|
DashboardIds []int64
|
2023-11-07 08:51:44 -06:00
|
|
|
// Deprecated: use FolderUID instead
|
|
|
|
FolderIds []int64
|
|
|
|
FolderUIDs []string
|
2023-11-22 07:20:22 -06:00
|
|
|
Permission dashboardaccess.PermissionType
|
2023-11-07 08:51:44 -06:00
|
|
|
Sort string
|
2019-10-11 10:08:15 -05:00
|
|
|
}
|
|
|
|
|
2022-02-04 06:41:15 -06:00
|
|
|
type Service interface {
|
2023-03-30 04:28:12 -05:00
|
|
|
SearchHandler(context.Context, *Query) (model.HitList, error)
|
2023-01-30 08:17:53 -06:00
|
|
|
SortOptions() []model.SortOption
|
2022-02-04 06:41:15 -06:00
|
|
|
}
|
|
|
|
|
2019-10-11 10:08:15 -05:00
|
|
|
type SearchService struct {
|
2022-05-24 08:24:55 -05:00
|
|
|
Cfg *setting.Cfg
|
2023-01-30 08:17:53 -06:00
|
|
|
sortOptions map[string]model.SortOption
|
2022-10-14 14:33:06 -05:00
|
|
|
sqlstore db.DB
|
2022-05-24 08:24:55 -05:00
|
|
|
starService star.Service
|
|
|
|
dashboardService dashboards.DashboardService
|
2019-10-11 10:08:15 -05:00
|
|
|
}
|
|
|
|
|
2023-03-30 04:28:12 -05:00
|
|
|
func (s *SearchService) SearchHandler(ctx context.Context, query *Query) (model.HitList, error) {
|
2023-03-16 04:20:07 -05:00
|
|
|
starredQuery := star.GetUserStarsQuery{
|
|
|
|
UserID: query.SignedInUser.UserID,
|
|
|
|
}
|
|
|
|
staredDashIDs, err := s.starService.GetByUser(ctx, &starredQuery)
|
|
|
|
if err != nil {
|
2023-03-30 04:28:12 -05:00
|
|
|
return nil, err
|
2023-03-16 04:20:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// No starred dashboards will be found
|
|
|
|
if query.IsStarred && len(staredDashIDs.UserStars) == 0 {
|
2023-03-30 04:28:12 -05:00
|
|
|
return model.HitList{}, nil
|
2023-03-16 04:20:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-25 04:10:35 -06:00
|
|
|
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Search).Inc()
|
2023-01-26 07:46:30 -06:00
|
|
|
dashboardQuery := dashboards.FindPersistedDashboardsQuery{
|
2022-06-02 14:56:01 -05:00
|
|
|
Title: query.Title,
|
|
|
|
SignedInUser: query.SignedInUser,
|
|
|
|
DashboardUIDs: query.DashboardUIDs,
|
|
|
|
DashboardIds: query.DashboardIds,
|
|
|
|
Type: query.Type,
|
2023-11-07 08:51:44 -06:00
|
|
|
FolderIds: query.FolderIds, // nolint:staticcheck
|
2023-08-04 04:43:47 -05:00
|
|
|
FolderUIDs: query.FolderUIDs,
|
2022-06-02 14:56:01 -05:00
|
|
|
Tags: query.Tags,
|
|
|
|
Limit: query.Limit,
|
|
|
|
Page: query.Page,
|
|
|
|
Permission: query.Permission,
|
2024-05-16 12:36:26 -05:00
|
|
|
IsDeleted: query.IsDeleted,
|
2020-04-20 09:20:45 -05:00
|
|
|
}
|
|
|
|
|
2020-04-27 07:16:03 -05:00
|
|
|
if sortOpt, exists := s.sortOptions[query.Sort]; exists {
|
2021-02-11 01:49:16 -06:00
|
|
|
dashboardQuery.Sort = sortOpt
|
2019-10-11 10:08:15 -05:00
|
|
|
}
|
|
|
|
|
2023-03-30 00:29:52 -05:00
|
|
|
hits, err := s.dashboardService.SearchDashboards(ctx, &dashboardQuery)
|
|
|
|
if err != nil {
|
2023-03-30 04:28:12 -05:00
|
|
|
return nil, err
|
2019-10-11 10:08:15 -05:00
|
|
|
}
|
|
|
|
|
2020-04-20 09:20:45 -05:00
|
|
|
if query.Sort == "" {
|
|
|
|
hits = sortedHits(hits)
|
|
|
|
}
|
2019-10-11 10:08:15 -05:00
|
|
|
|
2023-03-16 04:20:07 -05:00
|
|
|
// set starred dashboards
|
|
|
|
for _, dashboard := range hits {
|
|
|
|
if _, ok := staredDashIDs.UserStars[dashboard.ID]; ok {
|
|
|
|
dashboard.IsStarred = true
|
|
|
|
}
|
2019-10-11 10:08:15 -05:00
|
|
|
}
|
|
|
|
|
2023-03-16 04:20:07 -05:00
|
|
|
// filter for starred dashboards if requested
|
|
|
|
if !query.IsStarred {
|
2023-03-30 04:28:12 -05:00
|
|
|
return hits, nil
|
|
|
|
}
|
|
|
|
result := model.HitList{}
|
|
|
|
for _, dashboard := range hits {
|
|
|
|
if dashboard.IsStarred {
|
|
|
|
result = append(result, dashboard)
|
2023-03-16 04:20:07 -05:00
|
|
|
}
|
|
|
|
}
|
2023-03-30 04:28:12 -05:00
|
|
|
return result, nil
|
2019-10-11 10:08:15 -05:00
|
|
|
}
|
|
|
|
|
2023-01-30 08:17:53 -06:00
|
|
|
func sortedHits(unsorted model.HitList) model.HitList {
|
|
|
|
hits := make(model.HitList, 0)
|
2019-10-11 10:08:15 -05:00
|
|
|
hits = append(hits, unsorted...)
|
|
|
|
|
|
|
|
sort.Sort(hits)
|
|
|
|
|
|
|
|
for _, hit := range hits {
|
|
|
|
sort.Strings(hit.Tags)
|
|
|
|
}
|
|
|
|
|
|
|
|
return hits
|
|
|
|
}
|