mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Search API: Search by folder UID (#65040)
* Search: Attempt to support folderUID filter * Search: Use folder UID instead of ID for searching folders * Update swagger * Fix JSON property casing * Add integration test * Remove redundant query condition * Fix frontend test * Fix listing dashboards in General/root * Add support for fetching top level folders using `folderUIDs=` (empty string) query parameter * Add deprecation notice * Send uid of general in sql.ts * Use 'general' for query folderUIDs query param for fetching folder * Add tests * Fix FolderUIDFilter --------- Co-authored-by: Sofia Papagiannaki <1632407+papagian@users.noreply.github.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||
)
|
||||
|
||||
@@ -91,6 +92,52 @@ func (f FolderFilter) Where() (string, []interface{}) {
|
||||
return sqlIDin("dashboard.folder_id", f.IDs)
|
||||
}
|
||||
|
||||
type FolderUIDFilter struct {
|
||||
Dialect migrator.Dialect
|
||||
OrgID int64
|
||||
UIDs []string
|
||||
}
|
||||
|
||||
func (f FolderUIDFilter) Where() (string, []interface{}) {
|
||||
if len(f.UIDs) < 1 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
params := []interface{}{}
|
||||
includeGeneral := false
|
||||
for _, uid := range f.UIDs {
|
||||
if uid == folder.GeneralFolderUID {
|
||||
includeGeneral = true
|
||||
continue
|
||||
}
|
||||
params = append(params, uid)
|
||||
}
|
||||
|
||||
q := ""
|
||||
switch {
|
||||
case len(params) < 1:
|
||||
// do nothing
|
||||
case len(params) == 1:
|
||||
q = "dashboard.folder_id IN (SELECT id FROM dashboard WHERE org_id = ? AND uid = ?)"
|
||||
params = append([]interface{}{f.OrgID}, params...)
|
||||
default:
|
||||
sqlArray := "(?" + strings.Repeat(",?", len(params)-1) + ")"
|
||||
q = "dashboard.folder_id IN (SELECT id FROM dashboard WHERE org_id = ? AND uid IN " + sqlArray + ")"
|
||||
params = append([]interface{}{f.OrgID}, params...)
|
||||
}
|
||||
|
||||
if includeGeneral {
|
||||
if q == "" {
|
||||
q = "dashboard.folder_id = ? "
|
||||
} else {
|
||||
q = "(" + q + " OR dashboard.folder_id = ?)"
|
||||
}
|
||||
params = append(params, 0)
|
||||
}
|
||||
|
||||
return q, params
|
||||
}
|
||||
|
||||
type DashboardIDFilter struct {
|
||||
IDs []int64
|
||||
}
|
||||
|
||||
59
pkg/services/sqlstore/searchstore/filters_test.go
Normal file
59
pkg/services/sqlstore/searchstore/filters_test.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package searchstore_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/searchstore"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFolderUIDFilter(t *testing.T) {
|
||||
testCases := []struct {
|
||||
description string
|
||||
uids []string
|
||||
expectedSql string
|
||||
expectedParams []interface{}
|
||||
}{
|
||||
{
|
||||
description: "searching general folder",
|
||||
uids: []string{"general"},
|
||||
expectedSql: "dashboard.folder_id = ? ",
|
||||
expectedParams: []interface{}{0},
|
||||
},
|
||||
{
|
||||
description: "searching a specific folder",
|
||||
uids: []string{"abc-123"},
|
||||
expectedSql: "dashboard.folder_id IN (SELECT id FROM dashboard WHERE org_id = ? AND uid = ?)",
|
||||
expectedParams: []interface{}{int64(1), "abc-123"},
|
||||
},
|
||||
{
|
||||
description: "searching a specific folders",
|
||||
uids: []string{"abc-123", "def-456"},
|
||||
expectedSql: "dashboard.folder_id IN (SELECT id FROM dashboard WHERE org_id = ? AND uid IN (?,?))",
|
||||
expectedParams: []interface{}{int64(1), "abc-123", "def-456"},
|
||||
},
|
||||
{
|
||||
description: "searching a specific folders or general",
|
||||
uids: []string{"general", "abc-123", "def-456"},
|
||||
expectedSql: "(dashboard.folder_id IN (SELECT id FROM dashboard WHERE org_id = ? AND uid IN (?,?)) OR dashboard.folder_id = ?)",
|
||||
expectedParams: []interface{}{int64(1), "abc-123", "def-456", 0},
|
||||
},
|
||||
}
|
||||
|
||||
store := setupTestEnvironment(t)
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
f := searchstore.FolderUIDFilter{
|
||||
Dialect: store.GetDialect(),
|
||||
OrgID: 1,
|
||||
UIDs: tc.uids,
|
||||
}
|
||||
|
||||
sql, params := f.Where()
|
||||
|
||||
assert.Equal(t, tc.expectedSql, sql)
|
||||
assert.Equal(t, tc.expectedParams, params)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user