chore: replace artisanal FakeDashboardService with generated mock (#49276)
* chore: replace handmade FakeDashboardService with generated mock Maintaining a handcrafted FakeDashboardService is not sustainable now that we are in the process of moving the dashboard-related functions out of sqlstore. * remove dialect global variable
This commit is contained in:
@@ -15,19 +15,22 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/permissions"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/searchstore"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
type DashboardStore struct {
|
||||
sqlStore *sqlstore.SQLStore
|
||||
log log.Logger
|
||||
dialect migrator.Dialect
|
||||
}
|
||||
|
||||
// DashboardStore implements the Store interface
|
||||
var _ dashboards.Store = (*DashboardStore)(nil)
|
||||
|
||||
func ProvideDashboardStore(sqlStore *sqlstore.SQLStore) *DashboardStore {
|
||||
return &DashboardStore{sqlStore: sqlStore, log: log.New("dashboard-store")}
|
||||
return &DashboardStore{sqlStore: sqlStore, log: log.New("dashboard-store"), dialect: sqlStore.Dialect}
|
||||
}
|
||||
|
||||
func (d *DashboardStore) ValidateDashboardBeforeSave(dashboard *models.Dashboard, overwrite bool) (bool, error) {
|
||||
@@ -926,3 +929,143 @@ func (d *DashboardStore) GetDashboards(ctx context.Context, query *models.GetDas
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func (d *DashboardStore) SearchDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) error {
|
||||
res, err := d.FindDashboards(ctx, query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
makeQueryResult(query, res)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getHitType(item dashboards.DashboardSearchProjection) models.HitType {
|
||||
var hitType models.HitType
|
||||
if item.IsFolder {
|
||||
hitType = models.DashHitFolder
|
||||
} else {
|
||||
hitType = models.DashHitDB
|
||||
}
|
||||
|
||||
return hitType
|
||||
}
|
||||
|
||||
func makeQueryResult(query *models.FindPersistedDashboardsQuery, res []dashboards.DashboardSearchProjection) {
|
||||
query.Result = make([]*models.Hit, 0)
|
||||
hits := make(map[int64]*models.Hit)
|
||||
|
||||
for _, item := range res {
|
||||
hit, exists := hits[item.ID]
|
||||
if !exists {
|
||||
hit = &models.Hit{
|
||||
ID: item.ID,
|
||||
UID: item.UID,
|
||||
Title: item.Title,
|
||||
URI: "db/" + item.Slug,
|
||||
URL: models.GetDashboardFolderUrl(item.IsFolder, item.UID, item.Slug),
|
||||
Type: getHitType(item),
|
||||
FolderID: item.FolderID,
|
||||
FolderUID: item.FolderUID,
|
||||
FolderTitle: item.FolderTitle,
|
||||
Tags: []string{},
|
||||
}
|
||||
|
||||
if item.FolderID > 0 {
|
||||
hit.FolderURL = models.GetFolderUrl(item.FolderUID, item.FolderSlug)
|
||||
}
|
||||
|
||||
if query.Sort.MetaName != "" {
|
||||
hit.SortMeta = item.SortMeta
|
||||
hit.SortMetaName = query.Sort.MetaName
|
||||
}
|
||||
|
||||
query.Result = append(query.Result, hit)
|
||||
hits[item.ID] = hit
|
||||
}
|
||||
if len(item.Term) > 0 {
|
||||
hit.Tags = append(hit.Tags, item.Term)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DashboardStore) FindDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) ([]dashboards.DashboardSearchProjection, error) {
|
||||
filters := []interface{}{
|
||||
permissions.DashboardPermissionFilter{
|
||||
OrgRole: query.SignedInUser.OrgRole,
|
||||
OrgId: query.SignedInUser.OrgId,
|
||||
Dialect: d.dialect,
|
||||
UserId: query.SignedInUser.UserId,
|
||||
PermissionLevel: query.Permission,
|
||||
},
|
||||
}
|
||||
|
||||
if !ac.IsDisabled(d.sqlStore.Cfg) {
|
||||
// if access control is enabled, overwrite the filters so far
|
||||
filters = []interface{}{
|
||||
permissions.NewAccessControlDashboardPermissionFilter(query.SignedInUser, query.Permission, query.Type),
|
||||
}
|
||||
}
|
||||
|
||||
for _, filter := range query.Sort.Filter {
|
||||
filters = append(filters, filter)
|
||||
}
|
||||
|
||||
filters = append(filters, query.Filters...)
|
||||
|
||||
if query.OrgId != 0 {
|
||||
filters = append(filters, searchstore.OrgFilter{OrgId: query.OrgId})
|
||||
} else if query.SignedInUser.OrgId != 0 {
|
||||
filters = append(filters, searchstore.OrgFilter{OrgId: query.SignedInUser.OrgId})
|
||||
}
|
||||
|
||||
if len(query.Tags) > 0 {
|
||||
filters = append(filters, searchstore.TagsFilter{Tags: query.Tags})
|
||||
}
|
||||
|
||||
if len(query.DashboardIds) > 0 {
|
||||
filters = append(filters, searchstore.DashboardFilter{IDs: query.DashboardIds})
|
||||
}
|
||||
|
||||
if query.IsStarred {
|
||||
filters = append(filters, searchstore.StarredFilter{UserId: query.SignedInUser.UserId})
|
||||
}
|
||||
|
||||
if len(query.Title) > 0 {
|
||||
filters = append(filters, searchstore.TitleFilter{Dialect: d.dialect, Title: query.Title})
|
||||
}
|
||||
|
||||
if len(query.Type) > 0 {
|
||||
filters = append(filters, searchstore.TypeFilter{Dialect: d.dialect, Type: query.Type})
|
||||
}
|
||||
|
||||
if len(query.FolderIds) > 0 {
|
||||
filters = append(filters, searchstore.FolderFilter{IDs: query.FolderIds})
|
||||
}
|
||||
|
||||
var res []dashboards.DashboardSearchProjection
|
||||
sb := &searchstore.Builder{Dialect: d.dialect, Filters: filters}
|
||||
|
||||
limit := query.Limit
|
||||
if limit < 1 {
|
||||
limit = 1000
|
||||
}
|
||||
|
||||
page := query.Page
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
sql, params := sb.ToSQL(limit, page)
|
||||
|
||||
err := d.sqlStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
return sess.SQL(sql, params...).Find(&res)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user