mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 02:37:24 +08:00
region: make CustomizeFilterList logically
This commit is contained in:
@@ -433,26 +433,57 @@ func listItems(manager IModelManager, ctx context.Context, userCred mcclient.Tok
|
||||
q = q.Desc(orderByField)
|
||||
}
|
||||
}
|
||||
if limit > 0 {
|
||||
q = q.Limit(int(limit))
|
||||
customizeFilters, err := manager.CustomizeFilterList(ctx, q, userCred, queryDict)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if offset > 0 {
|
||||
q = q.Offset(int(offset))
|
||||
if customizeFilters.IsEmpty() {
|
||||
if limit > 0 {
|
||||
q = q.Limit(int(limit))
|
||||
}
|
||||
if offset > 0 {
|
||||
q = q.Offset(int(offset))
|
||||
}
|
||||
}
|
||||
retList, err := query2List(manager, ctx, userCred, q, queryDict)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
retConut := len(retList)
|
||||
retList, err = manager.CustomizeFilterList(ctx, userCred, queryDict, retList)
|
||||
|
||||
// apply customizeFilters
|
||||
retList, err = customizeFilters.DoApply(retList)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
if len(retList) != retConut {
|
||||
totalCnt = int64(len(retList))
|
||||
}
|
||||
retResult := modules.ListResult{Data: retList, Total: int(totalCnt), Limit: int(limit), Offset: int(offset)}
|
||||
return &retResult, nil
|
||||
paginate := false
|
||||
if !customizeFilters.IsEmpty() {
|
||||
// query not use Limit and Offset, do manual pagination
|
||||
paginate = true
|
||||
}
|
||||
return calculateListResult(retList, totalCnt, limit, offset, paginate), nil
|
||||
}
|
||||
|
||||
func calculateListResult(data []jsonutils.JSONObject, total, limit, offset int64, paginate bool) *modules.ListResult {
|
||||
if paginate {
|
||||
// do offset first
|
||||
if offset != 0 {
|
||||
if total > offset {
|
||||
data = data[offset:]
|
||||
} else {
|
||||
data = []jsonutils.JSONObject{}
|
||||
}
|
||||
}
|
||||
// do limit
|
||||
if total > limit {
|
||||
data = data[:limit]
|
||||
}
|
||||
}
|
||||
retResult := modules.ListResult{Data: data, Total: int(total), Limit: int(limit), Offset: int(offset)}
|
||||
return &retResult
|
||||
}
|
||||
|
||||
func (dispatcher *DBModelDispatcher) List(ctx context.Context, query jsonutils.JSONObject, ctxId string) (*modules.ListResult, error) {
|
||||
|
||||
@@ -29,7 +29,7 @@ type IModelManager interface {
|
||||
AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool
|
||||
ValidateListConditions(ctx context.Context, userCred mcclient.TokenCredential, query *jsonutils.JSONDict) (*jsonutils.JSONDict, error)
|
||||
ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error)
|
||||
CustomizeFilterList(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, retList []jsonutils.JSONObject) ([]jsonutils.JSONObject, error)
|
||||
CustomizeFilterList(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*CustomizeListFilters, error)
|
||||
ExtraSearchConditions(ctx context.Context, q *sqlchemy.SQuery, like string) []sqlchemy.ICondition
|
||||
|
||||
// fetch hook
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
)
|
||||
|
||||
type CustomizeListFilterFunc func(item jsonutils.JSONObject) (bool, error)
|
||||
|
||||
type CustomizeListFilters struct {
|
||||
filters []CustomizeListFilterFunc
|
||||
}
|
||||
|
||||
func NewCustomizeListFilters() *CustomizeListFilters {
|
||||
return &CustomizeListFilters{
|
||||
filters: []CustomizeListFilterFunc{},
|
||||
}
|
||||
}
|
||||
|
||||
func (f *CustomizeListFilters) Append(funcs ...CustomizeListFilterFunc) *CustomizeListFilters {
|
||||
f.filters = append(f.filters, funcs...)
|
||||
return f
|
||||
}
|
||||
|
||||
func (f CustomizeListFilters) Len() int {
|
||||
return len(f.filters)
|
||||
}
|
||||
|
||||
func (f CustomizeListFilters) IsEmpty() bool {
|
||||
return f.Len() == 0
|
||||
}
|
||||
|
||||
func (f CustomizeListFilters) DoApply(objs []jsonutils.JSONObject) ([]jsonutils.JSONObject, error) {
|
||||
filteredObjs := []jsonutils.JSONObject{}
|
||||
for _, obj := range objs {
|
||||
ok, err := f.singleApply(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ok {
|
||||
filteredObjs = append(filteredObjs, obj)
|
||||
}
|
||||
}
|
||||
return filteredObjs, nil
|
||||
}
|
||||
|
||||
func (f CustomizeListFilters) singleApply(obj jsonutils.JSONObject) (bool, error) {
|
||||
if f.IsEmpty() {
|
||||
return true, nil
|
||||
}
|
||||
for _, filter := range f.filters {
|
||||
ok, err := filter(obj)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
@@ -75,8 +75,8 @@ func (manager *SModelBaseManager) ListItemFilter(ctx context.Context, q *sqlchem
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (manager *SModelBaseManager) CustomizeFilterList(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, retList []jsonutils.JSONObject) ([]jsonutils.JSONObject, error) {
|
||||
return retList, nil
|
||||
func (manager *SModelBaseManager) CustomizeFilterList(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*CustomizeListFilters, error) {
|
||||
return NewCustomizeListFilters(), nil
|
||||
}
|
||||
|
||||
func (manager *SModelBaseManager) ExtraSearchConditions(ctx context.Context, q *sqlchemy.SQuery, like string) []sqlchemy.ICondition {
|
||||
|
||||
@@ -1291,28 +1291,28 @@ func (self *SNetwork) isManaged() bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) CustomizeFilterList(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, retList []jsonutils.JSONObject) ([]jsonutils.JSONObject, error) {
|
||||
func (manager *SNetworkManager) CustomizeFilterList(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*db.CustomizeListFilters, error) {
|
||||
filters := db.NewCustomizeListFilters()
|
||||
|
||||
if query.Contains("ip") {
|
||||
ip, _ := query.GetString("ip")
|
||||
ipInt, err := netutils.NewIPV4Addr(ip)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := make([]jsonutils.JSONObject, 0)
|
||||
for i := 0; i < len(retList); i++ {
|
||||
guestIpStart, _ := retList[i].GetString("guest_ip_start")
|
||||
guestIpEnd, _ := retList[i].GetString("guest_ip_end")
|
||||
|
||||
ipFilter := func(obj jsonutils.JSONObject) (bool, error) {
|
||||
guestIpStart, _ := obj.GetString("guest_ip_start")
|
||||
guestIpEnd, _ := obj.GetString("guest_ip_end")
|
||||
guestIpStartInt, _ := netutils.NewIPV4Addr(guestIpStart)
|
||||
guestIpEndInt, _ := netutils.NewIPV4Addr(guestIpEnd)
|
||||
ipRange := netutils.NewIPV4AddrRange(guestIpStartInt, guestIpEndInt)
|
||||
if ipRange.Contains(ipInt) {
|
||||
ret = append(ret, retList[i])
|
||||
}
|
||||
return ipRange.Contains(ipInt), nil
|
||||
}
|
||||
return ret, nil
|
||||
} else {
|
||||
return manager.SStatusStandaloneResourceBaseManager.CustomizeFilterList(ctx, userCred, query, retList)
|
||||
|
||||
filters.Append(ipFilter)
|
||||
}
|
||||
return filters, nil
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
|
||||
|
||||
Reference in New Issue
Block a user