Search: Fixes search limits and adds a page parameter (#16458)

* Search: Fixes search limits and adds a page parameter

This adds a page parameter to search api without adding
any major breaking change.

It does at an api validation error when trying to use
a limit beyond 5000. This is a breaking change. We could
remove this and have it only in the docs and describe that this
is a limit that grafana will apply silently.

Fixes #16049

* Fix: Corrected wrong array slice change

* Docs: minor docs fix

* Search: fixed folder tests

* Fixed: Moved limit to correct inner query

* Search: moving limit check and page check

* Search: limit in handler is no longer needed
This commit is contained in:
Torkel Ödegaard
2019-04-17 13:07:50 +02:00
committed by GitHub
parent 9cc67e49b4
commit 8b0dd4244b
12 changed files with 73 additions and 42 deletions
+1 -6
View File
@@ -197,12 +197,7 @@ type DashboardSearchProjection struct {
}
func findDashboards(query *search.FindPersistedDashboardsQuery) ([]DashboardSearchProjection, error) {
limit := query.Limit
if limit == 0 {
limit = 1000
}
sb := NewSearchBuilder(query.SignedInUser, limit, query.Permission).
sb := NewSearchBuilder(query.SignedInUser, query.Limit, query.Page, query.Permission).
WithTags(query.Tags).
WithDashboardIdsIn(query.DashboardIds)
+29
View File
@@ -259,6 +259,35 @@ func TestDashboardDataAccess(t *testing.T) {
So(hit.FolderTitle, ShouldEqual, "")
})
Convey("Should be able to limit search", func() {
query := search.FindPersistedDashboardsQuery{
OrgId: 1,
Limit: 1,
SignedInUser: &m.SignedInUser{OrgId: 1, OrgRole: m.ROLE_EDITOR},
}
err := SearchDashboards(&query)
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 1)
So(query.Result[0].Title, ShouldEqual, "1 test dash folder")
})
Convey("Should be able to search beyond limit using paging", func() {
query := search.FindPersistedDashboardsQuery{
OrgId: 1,
Limit: 1,
Page: 2,
SignedInUser: &m.SignedInUser{OrgId: 1, OrgRole: m.ROLE_EDITOR},
}
err := SearchDashboards(&query)
So(err, ShouldBeNil)
So(len(query.Result), ShouldEqual, 1)
So(query.Result[0].Title, ShouldEqual, "test dash 23")
})
Convey("Should be able to search for a dashboard folder's children", func() {
query := search.FindPersistedDashboardsQuery{
OrgId: 1,
+21 -11
View File
@@ -11,7 +11,8 @@ type SearchBuilder struct {
SqlBuilder
tags []string
isStarred bool
limit int
limit int64
page int64
signedInUser *m.SignedInUser
whereDashboardIdsIn []int64
whereTitle string
@@ -21,10 +22,21 @@ type SearchBuilder struct {
permission m.PermissionType
}
func NewSearchBuilder(signedInUser *m.SignedInUser, limit int, permission m.PermissionType) *SearchBuilder {
func NewSearchBuilder(signedInUser *m.SignedInUser, limit int64, page int64, permission m.PermissionType) *SearchBuilder {
// Default to page 1
if page < 1 {
page = 1
}
// default limit
if limit <= 0 {
limit = 1000
}
searchBuilder := &SearchBuilder{
signedInUser: signedInUser,
limit: limit,
page: page,
permission: permission,
}
@@ -88,12 +100,16 @@ func (sb *SearchBuilder) ToSql() (string, []interface{}) {
sb.buildMainQuery()
}
sb.sql.WriteString(`
ORDER BY dashboard.id ` + dialect.LimitOffset(sb.limit, (sb.page-1)*sb.limit) + `) as ids
INNER JOIN dashboard on ids.id = dashboard.id
`)
sb.sql.WriteString(`
LEFT OUTER JOIN dashboard folder on folder.id = dashboard.folder_id
LEFT OUTER JOIN dashboard_tag on dashboard.id = dashboard_tag.dashboard_id`)
sb.sql.WriteString(" ORDER BY dashboard.title ASC" + dialect.Limit(5000))
sb.sql.WriteString(" ORDER BY dashboard.title ASC")
return sb.sql.String(), sb.params
}
@@ -133,12 +149,7 @@ func (sb *SearchBuilder) buildTagQuery() {
sb.buildSearchWhereClause()
// this ends the inner select (tag filtered part)
sb.sql.WriteString(`
GROUP BY dashboard.id HAVING COUNT(dashboard.id) >= ?
ORDER BY dashboard.id` + dialect.Limit(int64(sb.limit)) + `) as ids
INNER JOIN dashboard on ids.id = dashboard.id
`)
sb.sql.WriteString(`GROUP BY dashboard.id HAVING COUNT(dashboard.id) >= ? `)
sb.params = append(sb.params, len(sb.tags))
}
@@ -152,7 +163,6 @@ func (sb *SearchBuilder) buildMainQuery() {
sb.sql.WriteString(` WHERE `)
sb.buildSearchWhereClause()
sb.sql.WriteString(` ORDER BY dashboard.title` + dialect.Limit(int64(sb.limit)) + `) as ids INNER JOIN dashboard on ids.id = dashboard.id `)
}
func (sb *SearchBuilder) buildSearchWhereClause() {
+1 -1
View File
@@ -14,7 +14,7 @@ func TestSearchBuilder(t *testing.T) {
UserId: 1,
}
sb := NewSearchBuilder(signedInUser, 1000, m.PERMISSION_VIEW)
sb := NewSearchBuilder(signedInUser, 1000, 0, m.PERMISSION_VIEW)
Convey("When building a normal search", func() {
sql, params := sb.IsStarred().WithTitle("test").ToSql()