EntityStore: support filtering by labels (#59905)
* label filtering * filtering in sql * filtering in sql group by * label is unique - no need for distinct * capitalize * fix capitalization
This commit is contained in:
@@ -17,6 +17,11 @@ func (q *selectQuery) addWhere(f string, val interface{}) {
|
||||
q.where = append(q.where, f+"=?")
|
||||
}
|
||||
|
||||
func (q *selectQuery) addWhereInSubquery(f string, subquery string, subqueryArgs []interface{}) {
|
||||
q.args = append(q.args, subqueryArgs...)
|
||||
q.where = append(q.where, f+" IN ("+subquery+")")
|
||||
}
|
||||
|
||||
func (q *selectQuery) addWhereIn(f string, vals []string) {
|
||||
count := len(vals)
|
||||
if count > 1 {
|
||||
|
||||
@@ -623,7 +623,7 @@ func (s *sqlEntityServer) Search(ctx context.Context, r *entity.EntitySearchRequ
|
||||
return nil, fmt.Errorf("missing user in context")
|
||||
}
|
||||
|
||||
if r.NextPageToken != "" || len(r.Sort) > 0 || len(r.Labels) > 0 {
|
||||
if r.NextPageToken != "" || len(r.Sort) > 0 {
|
||||
return nil, fmt.Errorf("not yet supported")
|
||||
}
|
||||
|
||||
@@ -637,6 +637,7 @@ func (s *sqlEntityServer) Search(ctx context.Context, r *entity.EntitySearchRequ
|
||||
if r.WithBody {
|
||||
fields = append(fields, "body")
|
||||
}
|
||||
|
||||
if r.WithLabels {
|
||||
fields = append(fields, "labels")
|
||||
}
|
||||
@@ -644,25 +645,40 @@ func (s *sqlEntityServer) Search(ctx context.Context, r *entity.EntitySearchRequ
|
||||
fields = append(fields, "fields")
|
||||
}
|
||||
|
||||
selectQuery := selectQuery{
|
||||
entityQuery := selectQuery{
|
||||
fields: fields,
|
||||
from: "entity", // the table
|
||||
args: []interface{}{},
|
||||
limit: int(r.Limit),
|
||||
oneExtra: true, // request one more than the limit (and show next token if it exists)
|
||||
}
|
||||
selectQuery.addWhere("tenant_id", user.OrgID)
|
||||
entityQuery.addWhere("tenant_id", user.OrgID)
|
||||
|
||||
if len(r.Kind) > 0 {
|
||||
selectQuery.addWhereIn("kind", r.Kind)
|
||||
entityQuery.addWhereIn("kind", r.Kind)
|
||||
}
|
||||
|
||||
// Folder UID or OID?
|
||||
if r.Folder != "" {
|
||||
selectQuery.addWhere("folder", r.Folder)
|
||||
entityQuery.addWhere("folder", r.Folder)
|
||||
}
|
||||
|
||||
query, args := selectQuery.toQuery()
|
||||
if len(r.Labels) > 0 {
|
||||
var args []interface{}
|
||||
var conditions []string
|
||||
for labelKey, labelValue := range r.Labels {
|
||||
args = append(args, labelKey)
|
||||
args = append(args, labelValue)
|
||||
conditions = append(conditions, "(label = ? AND value = ?)")
|
||||
}
|
||||
joinedConditions := strings.Join(conditions, " OR ")
|
||||
query := "SELECT grn FROM entity_labels WHERE " + joinedConditions + " GROUP BY grn HAVING COUNT(label) = ?"
|
||||
args = append(args, len(r.Labels))
|
||||
|
||||
entityQuery.addWhereInSubquery("grn", query, args)
|
||||
}
|
||||
|
||||
query, args := entityQuery.toQuery()
|
||||
|
||||
fmt.Printf("\n\n-------------\n")
|
||||
fmt.Printf("%s\n", query)
|
||||
@@ -704,7 +720,7 @@ func (s *sqlEntityServer) Search(ctx context.Context, r *entity.EntitySearchRequ
|
||||
}
|
||||
|
||||
// found one more than requested
|
||||
if len(rsp.Results) >= selectQuery.limit {
|
||||
if len(rsp.Results) >= entityQuery.limit {
|
||||
// TODO? should this encode start+offset?
|
||||
rsp.NextPageToken = oid
|
||||
break
|
||||
@@ -732,5 +748,6 @@ func (s *sqlEntityServer) Search(ctx context.Context, r *entity.EntitySearchRequ
|
||||
|
||||
rsp.Results = append(rsp.Results, result)
|
||||
}
|
||||
|
||||
return rsp, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user