Search: add sort information in dashboard results (#30609)

* Search: add SortMeta in dashboard results

* fix integration tests

* trim SortMeta

* fix searchstore tests

* Update pkg/services/sqlstore/dashboard.go

Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>

Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>
This commit is contained in:
Agnès Toulet
2021-02-11 08:49:16 +01:00
committed by GitHub
co-authored by Emil Tullstedt
parent 25117f5af5
commit 3303e28b38
15 changed files with 111 additions and 87 deletions
+23 -15
View File
@@ -1,6 +1,7 @@
package sqlstore
import (
"fmt"
"strings"
"time"
@@ -203,16 +204,17 @@ func GetDashboard(query *models.GetDashboardQuery) error {
}
type DashboardSearchProjection struct {
Id int64
Uid string
ID int64 `xorm:"id"`
UID string `xorm:"uid"`
Title string
Slug string
Term string
IsFolder bool
FolderId int64
FolderUid string
FolderID int64 `xorm:"folder_id"`
FolderUID string `xorm:"folder_uid"`
FolderSlug string
FolderTitle string
SortMeta int64
}
func findDashboards(query *search.FindPersistedDashboardsQuery) ([]DashboardSearchProjection, error) {
@@ -226,7 +228,9 @@ func findDashboards(query *search.FindPersistedDashboardsQuery) ([]DashboardSear
},
}
filters = append(filters, query.Filters...)
for _, filter := range query.Sort.Filter {
filters = append(filters, filter)
}
if query.OrgId != 0 {
filters = append(filters, searchstore.OrgFilter{OrgId: query.OrgId})
@@ -307,27 +311,31 @@ func makeQueryResult(query *search.FindPersistedDashboardsQuery, res []Dashboard
hits := make(map[int64]*search.Hit)
for _, item := range res {
hit, exists := hits[item.Id]
hit, exists := hits[item.ID]
if !exists {
hit = &search.Hit{
Id: item.Id,
Uid: item.Uid,
ID: item.ID,
UID: item.UID,
Title: item.Title,
Uri: "db/" + item.Slug,
Url: models.GetDashboardFolderUrl(item.IsFolder, item.Uid, item.Slug),
URI: "db/" + item.Slug,
URL: models.GetDashboardFolderUrl(item.IsFolder, item.UID, item.Slug),
Type: getHitType(item),
FolderId: item.FolderId,
FolderUid: item.FolderUid,
FolderID: item.FolderID,
FolderUID: item.FolderUID,
FolderTitle: item.FolderTitle,
Tags: []string{},
}
if item.FolderId > 0 {
hit.FolderUrl = models.GetFolderUrl(item.FolderUid, item.FolderSlug)
if item.FolderID > 0 {
hit.FolderURL = models.GetFolderUrl(item.FolderUID, item.FolderSlug)
}
if query.Sort.MetaName != "" {
hit.SortMeta = strings.TrimSpace(fmt.Sprintf("%d %s", item.SortMeta, query.Sort.MetaName))
}
query.Result = append(query.Result, hit)
hits[item.Id] = hit
hits[item.ID] = hit
}
if len(item.Term) > 0 {
hit.Tags = append(hit.Tags, item.Term)
+32 -32
View File
@@ -33,8 +33,8 @@ func TestDashboardFolderDataAccess(t *testing.T) {
err := SearchDashboards(query)
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 2)
So(query.Result[0].Id, ShouldEqual, folder.Id)
So(query.Result[1].Id, ShouldEqual, dashInRoot.Id)
So(query.Result[0].ID, ShouldEqual, folder.Id)
So(query.Result[1].ID, ShouldEqual, dashInRoot.Id)
})
})
@@ -57,7 +57,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 1)
So(query.Result[0].Id, ShouldEqual, dashInRoot.Id)
So(query.Result[0].ID, ShouldEqual, dashInRoot.Id)
})
Convey("when the user is given permission", func() {
@@ -75,8 +75,8 @@ func TestDashboardFolderDataAccess(t *testing.T) {
err := SearchDashboards(query)
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 2)
So(query.Result[0].Id, ShouldEqual, folder.Id)
So(query.Result[1].Id, ShouldEqual, dashInRoot.Id)
So(query.Result[0].ID, ShouldEqual, folder.Id)
So(query.Result[1].ID, ShouldEqual, dashInRoot.Id)
})
})
@@ -94,8 +94,8 @@ func TestDashboardFolderDataAccess(t *testing.T) {
err := SearchDashboards(query)
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 2)
So(query.Result[0].Id, ShouldEqual, folder.Id)
So(query.Result[1].Id, ShouldEqual, dashInRoot.Id)
So(query.Result[0].ID, ShouldEqual, folder.Id)
So(query.Result[1].ID, ShouldEqual, dashInRoot.Id)
})
})
})
@@ -116,7 +116,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
err := SearchDashboards(query)
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 1)
So(query.Result[0].Id, ShouldEqual, dashInRoot.Id)
So(query.Result[0].ID, ShouldEqual, dashInRoot.Id)
})
Convey("when the user is given permission to child", func() {
@@ -128,8 +128,8 @@ func TestDashboardFolderDataAccess(t *testing.T) {
err := SearchDashboards(query)
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 2)
So(query.Result[0].Id, ShouldEqual, childDash.Id)
So(query.Result[1].Id, ShouldEqual, dashInRoot.Id)
So(query.Result[0].ID, ShouldEqual, childDash.Id)
So(query.Result[1].ID, ShouldEqual, dashInRoot.Id)
})
})
@@ -147,9 +147,9 @@ func TestDashboardFolderDataAccess(t *testing.T) {
err := SearchDashboards(query)
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 3)
So(query.Result[0].Id, ShouldEqual, folder.Id)
So(query.Result[1].Id, ShouldEqual, childDash.Id)
So(query.Result[2].Id, ShouldEqual, dashInRoot.Id)
So(query.Result[0].ID, ShouldEqual, folder.Id)
So(query.Result[1].ID, ShouldEqual, childDash.Id)
So(query.Result[2].ID, ShouldEqual, dashInRoot.Id)
})
})
})
@@ -171,10 +171,10 @@ func TestDashboardFolderDataAccess(t *testing.T) {
err := SearchDashboards(query)
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 4)
So(query.Result[0].Id, ShouldEqual, folder1.Id)
So(query.Result[1].Id, ShouldEqual, folder2.Id)
So(query.Result[2].Id, ShouldEqual, childDash1.Id)
So(query.Result[3].Id, ShouldEqual, dashInRoot.Id)
So(query.Result[0].ID, ShouldEqual, folder1.Id)
So(query.Result[1].ID, ShouldEqual, folder2.Id)
So(query.Result[2].ID, ShouldEqual, childDash1.Id)
So(query.Result[3].ID, ShouldEqual, dashInRoot.Id)
})
})
@@ -197,7 +197,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
err := SearchDashboards(query)
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 1)
So(query.Result[0].Id, ShouldEqual, dashInRoot.Id)
So(query.Result[0].ID, ShouldEqual, dashInRoot.Id)
})
})
Convey("and a dashboard is moved from folder with acl to the folder without an acl", func() {
@@ -212,10 +212,10 @@ func TestDashboardFolderDataAccess(t *testing.T) {
err := SearchDashboards(query)
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 4)
So(query.Result[0].Id, ShouldEqual, folder2.Id)
So(query.Result[1].Id, ShouldEqual, childDash1.Id)
So(query.Result[2].Id, ShouldEqual, childDash2.Id)
So(query.Result[3].Id, ShouldEqual, dashInRoot.Id)
So(query.Result[0].ID, ShouldEqual, folder2.Id)
So(query.Result[1].ID, ShouldEqual, childDash1.Id)
So(query.Result[2].ID, ShouldEqual, childDash2.Id)
So(query.Result[3].ID, ShouldEqual, dashInRoot.Id)
})
})
@@ -236,10 +236,10 @@ func TestDashboardFolderDataAccess(t *testing.T) {
err := SearchDashboards(query)
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 4)
So(query.Result[0].Id, ShouldEqual, folder2.Id)
So(query.Result[1].Id, ShouldEqual, childDash1.Id)
So(query.Result[2].Id, ShouldEqual, childDash2.Id)
So(query.Result[3].Id, ShouldEqual, dashInRoot.Id)
So(query.Result[0].ID, ShouldEqual, folder2.Id)
So(query.Result[1].ID, ShouldEqual, childDash1.Id)
So(query.Result[2].ID, ShouldEqual, childDash2.Id)
So(query.Result[3].ID, ShouldEqual, dashInRoot.Id)
})
})
})
@@ -267,8 +267,8 @@ func TestDashboardFolderDataAccess(t *testing.T) {
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 2)
So(query.Result[0].Id, ShouldEqual, folder1.Id)
So(query.Result[1].Id, ShouldEqual, folder2.Id)
So(query.Result[0].ID, ShouldEqual, folder1.Id)
So(query.Result[1].ID, ShouldEqual, folder2.Id)
})
Convey("should have write access to all folders and dashboards", func() {
@@ -320,8 +320,8 @@ func TestDashboardFolderDataAccess(t *testing.T) {
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 2)
So(query.Result[0].Id, ShouldEqual, folder1.Id)
So(query.Result[1].Id, ShouldEqual, folder2.Id)
So(query.Result[0].ID, ShouldEqual, folder1.Id)
So(query.Result[1].ID, ShouldEqual, folder2.Id)
})
Convey("should have edit access to folders with default ACL", func() {
@@ -352,7 +352,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 1)
So(query.Result[0].Id, ShouldEqual, folder2.Id)
So(query.Result[0].ID, ShouldEqual, folder2.Id)
})
Convey("should have edit permission in folders", func() {
@@ -416,7 +416,7 @@ func TestDashboardFolderDataAccess(t *testing.T) {
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 1)
So(query.Result[0].Id, ShouldEqual, folder1.Id)
So(query.Result[0].ID, ShouldEqual, folder1.Id)
})
Convey("should not have edit permission in folders", func() {
+8 -8
View File
@@ -277,7 +277,7 @@ func TestDashboardDataAccess(t *testing.T) {
So(len(query.Result), ShouldEqual, 1)
hit := query.Result[0]
So(hit.Type, ShouldEqual, search.DashHitFolder)
So(hit.Url, ShouldEqual, fmt.Sprintf("/dashboards/f/%s/%s", savedFolder.Uid, savedFolder.Slug))
So(hit.URL, ShouldEqual, fmt.Sprintf("/dashboards/f/%s/%s", savedFolder.Uid, savedFolder.Slug))
So(hit.FolderTitle, ShouldEqual, "")
})
@@ -337,12 +337,12 @@ func TestDashboardDataAccess(t *testing.T) {
So(len(query.Result), ShouldEqual, 2)
hit := query.Result[0]
So(hit.Id, ShouldEqual, savedDash.Id)
So(hit.Url, ShouldEqual, fmt.Sprintf("/d/%s/%s", savedDash.Uid, savedDash.Slug))
So(hit.FolderId, ShouldEqual, savedFolder.Id)
So(hit.FolderUid, ShouldEqual, savedFolder.Uid)
So(hit.ID, ShouldEqual, savedDash.Id)
So(hit.URL, ShouldEqual, fmt.Sprintf("/d/%s/%s", savedDash.Uid, savedDash.Slug))
So(hit.FolderID, ShouldEqual, savedFolder.Id)
So(hit.FolderUID, ShouldEqual, savedFolder.Uid)
So(hit.FolderTitle, ShouldEqual, savedFolder.Title)
So(hit.FolderUrl, ShouldEqual, fmt.Sprintf("/dashboards/f/%s/%s", savedFolder.Uid, savedFolder.Slug))
So(hit.FolderURL, ShouldEqual, fmt.Sprintf("/dashboards/f/%s/%s", savedFolder.Uid, savedFolder.Slug))
})
Convey("Should be able to search for dashboard by dashboard ids", func() {
@@ -436,8 +436,8 @@ func TestDashboard_SortingOptions(t *testing.T) {
require.NoError(t, err)
require.Len(t, dashboards, 2)
assert.Equal(t, dashA.Id, dashboards[0].Id)
assert.Equal(t, dashB.Id, dashboards[1].Id)
assert.Equal(t, dashA.Id, dashboards[0].ID)
assert.Equal(t, dashB.Id, dashboards[1].ID)
})
}
+9 -2
View File
@@ -55,8 +55,15 @@ func (b *Builder) buildSelect() {
dashboard.folder_id,
folder.uid AS folder_uid,
folder.slug AS folder_slug,
folder.title AS folder_title
FROM `)
folder.title AS folder_title `)
for _, f := range b.Filters {
if f, ok := f.(FilterSelect); ok {
b.sql.WriteString(fmt.Sprintf(", %s", f.Select()))
}
}
b.sql.WriteString(` FROM `)
}
func (b *Builder) applyFilters() (ordering string) {
@@ -33,6 +33,10 @@ type FilterLeftJoin interface {
LeftJoin() string
}
type FilterSelect interface {
Select() string
}
const (
TypeFolder = "dash-folder"
TypeDashboard = "dash-db"
@@ -58,10 +58,10 @@ func TestBuilder_EqualResults_Basic(t *testing.T) {
require.NoError(t, err)
assert.Len(t, res, 1)
res[0].Uid = ""
res[0].UID = ""
assert.EqualValues(t, []sqlstore.DashboardSearchProjection{
{
Id: 1,
ID: 1,
Title: "A",
Slug: "a",
Term: "templated",