mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
fix: tag filter with no value revisit
This commit is contained in:
@@ -21,6 +21,7 @@ import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/util/rbacscope"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
@@ -58,23 +59,30 @@ func ObjectIdQueryWithPolicyResult(ctx context.Context, q *sqlchemy.SQuery, mana
|
||||
}
|
||||
|
||||
func ObjectIdQueryWithTagFilters(ctx context.Context, q *sqlchemy.SQuery, idField string, modelName string, filters tagutils.STagFilters) *sqlchemy.SQuery {
|
||||
if len(filters.Filters) > 0 {
|
||||
sq := objIdQueryWithTags(ctx, modelName, filters.Filters)
|
||||
if sq != nil {
|
||||
sqq := sq.SubQuery()
|
||||
q = q.Join(sqq, sqlchemy.Equals(q.Field(idField), sqq.Field("obj_id")))
|
||||
if len(filters.Filters) > 0 || len(filters.NoFilters) > 0 {
|
||||
idSubQ := q.Copy().SubQuery().Query()
|
||||
idSubQ.AppendField(sqlchemy.DISTINCT(idField, idSubQ.Field(idField)))
|
||||
subQ := idSubQ.SubQuery()
|
||||
if len(filters.Filters) > 0 {
|
||||
sq := objIdQueryWithTags(ctx, subQ, idField, modelName, filters.Filters)
|
||||
if sq != nil {
|
||||
sqq := sq.SubQuery()
|
||||
q = q.Join(sqq, sqlchemy.Equals(q.Field(idField), sqq.Field(idField)))
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(filters.NoFilters) > 0 {
|
||||
sq := objIdQueryWithTags(ctx, modelName, filters.NoFilters)
|
||||
if sq != nil {
|
||||
q = q.Filter(sqlchemy.NotIn(q.Field(idField), sq.SubQuery()))
|
||||
if len(filters.NoFilters) > 0 {
|
||||
sq := objIdQueryWithTags(ctx, subQ, idField, modelName, filters.NoFilters)
|
||||
if sq != nil {
|
||||
sqq := sq.SubQuery()
|
||||
q = q.LeftJoin(sqq, sqlchemy.Equals(q.Field(idField), sqq.Field(idField)))
|
||||
q = q.Filter(sqlchemy.IsNull(sqq.Field(idField)))
|
||||
}
|
||||
}
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
func objIdQueryWithTags(ctx context.Context, modelName string, tagsList []map[string][]string) *sqlchemy.SQuery {
|
||||
func objIdQueryWithTags(ctx context.Context, objIdSubQ *sqlchemy.SSubQuery, idField string, modelName string, tagsList []map[string][]string) *sqlchemy.SQuery {
|
||||
manager := GetMetadaManagerInContext(ctx)
|
||||
metadataResQ := manager.Query().Equals("obj_type", modelName).SubQuery()
|
||||
|
||||
@@ -83,29 +91,37 @@ func objIdQueryWithTags(ctx context.Context, modelName string, tagsList []map[st
|
||||
if len(tags) == 0 {
|
||||
continue
|
||||
}
|
||||
metadataView := metadataResQ.Query(metadataResQ.Field("obj_id").Label("obj_id"))
|
||||
objIdQ := objIdSubQ.Query()
|
||||
objIdQ = objIdQ.AppendField(objIdQ.Field(idField))
|
||||
for key, val := range tags {
|
||||
q := metadataResQ.Query(metadataResQ.Field("id"))
|
||||
q = q.Equals("key", key)
|
||||
sq := metadataResQ.Query().Equals("key", key).SubQuery()
|
||||
objIdQ = objIdQ.LeftJoin(sq, sqlchemy.Equals(objIdQ.Field(idField), sq.Field("obj_id")))
|
||||
if len(val) > 0 {
|
||||
q = q.In("value", val)
|
||||
if utils.IsInArray(tagutils.NoValue, val) {
|
||||
objIdQ = objIdQ.Filter(sqlchemy.OR(
|
||||
sqlchemy.In(sq.Field("value"), val),
|
||||
sqlchemy.IsNull(sq.Field("value")),
|
||||
))
|
||||
} else {
|
||||
objIdQ = objIdQ.Filter(sqlchemy.In(sq.Field("value"), val))
|
||||
}
|
||||
} else {
|
||||
objIdQ = objIdQ.Filter(sqlchemy.IsNotNull(sq.Field("obj_id")))
|
||||
}
|
||||
sq := q.SubQuery()
|
||||
metadataView = metadataView.Join(sq, sqlchemy.Equals(metadataView.Field("id"), sq.Field("id")))
|
||||
}
|
||||
queries = append(queries, metadataView.Distinct())
|
||||
queries = append(queries, objIdQ.Distinct())
|
||||
}
|
||||
if len(queries) == 0 {
|
||||
return nil
|
||||
}
|
||||
var query sqlchemy.IQuery
|
||||
var query *sqlchemy.SQuery
|
||||
if len(queries) == 1 {
|
||||
query = queries[0]
|
||||
query = queries[0].(*sqlchemy.SQuery)
|
||||
} else {
|
||||
uq, _ := sqlchemy.UnionWithError(queries...)
|
||||
query = uq.Query()
|
||||
}
|
||||
return query.SubQuery().Query()
|
||||
return query
|
||||
}
|
||||
|
||||
func (meta *SMetadataResourceBaseModelManager) ListItemFilter(
|
||||
|
||||
Reference in New Issue
Block a user