mirror of
https://github.com/grafana/grafana.git
synced 2026-08-09 04:38:16 -05:00
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:
@@ -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)
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user