Skip to content

Commit

Permalink
Filter resources on default fields
Browse files Browse the repository at this point in the history
  • Loading branch information
nathan-jenan-rancher committed May 15, 2018
1 parent 1a2bcea commit 7fed25b
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 28 deletions.
12 changes: 6 additions & 6 deletions api/handler/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import (
"github.com/rancher/norman/types/convert"
)

func QueryFilter(opts *types.QueryOptions, data []map[string]interface{}) []map[string]interface{} {
return ApplyQueryOptions(opts, data)
func QueryFilter(opts *types.QueryOptions, schema *types.Schema, data []map[string]interface{}) []map[string]interface{} {
return ApplyQueryOptions(opts, schema, data)
}

func ApplyQueryOptions(options *types.QueryOptions, data []map[string]interface{}) []map[string]interface{} {
data = ApplyQueryConditions(options.Conditions, data)
func ApplyQueryOptions(options *types.QueryOptions, schema *types.Schema, data []map[string]interface{}) []map[string]interface{} {
data = ApplyQueryConditions(options.Conditions, schema, data)
data = ApplySort(options.Sort, data)
return ApplyPagination(options.Pagination, data)
}
Expand All @@ -35,13 +35,13 @@ func ApplySort(sortOpts types.Sort, data []map[string]interface{}) []map[string]
return data
}

func ApplyQueryConditions(conditions []*types.QueryCondition, data []map[string]interface{}) []map[string]interface{} {
func ApplyQueryConditions(conditions []*types.QueryCondition, schema *types.Schema, data []map[string]interface{}) []map[string]interface{} {
var result []map[string]interface{}

outer:
for _, item := range data {
for _, condition := range conditions {
if !condition.Valid(item) {
if !condition.Valid(schema, item) {
continue outer
}
}
Expand Down
10 changes: 5 additions & 5 deletions store/wrapper/wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (s *StoreWrapper) ByID(apiContext *types.APIContext, schema *types.Schema,

return apiContext.FilterObject(&types.QueryOptions{
Conditions: apiContext.SubContextAttributeProvider.Query(apiContext, schema),
}, data), nil
}, schema, data), nil
}

func (s *StoreWrapper) List(apiContext *types.APIContext, schema *types.Schema, opts *types.QueryOptions) ([]map[string]interface{}, error) {
Expand All @@ -38,7 +38,7 @@ func (s *StoreWrapper) List(apiContext *types.APIContext, schema *types.Schema,
return nil, err
}

return apiContext.FilterList(opts, data), nil
return apiContext.FilterList(opts, schema, data), nil
}

func (s *StoreWrapper) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) {
Expand All @@ -50,7 +50,7 @@ func (s *StoreWrapper) Watch(apiContext *types.APIContext, schema *types.Schema,
return convert.Chan(c, func(data map[string]interface{}) map[string]interface{} {
return apiContext.FilterObject(&types.QueryOptions{
Conditions: apiContext.SubContextAttributeProvider.Query(apiContext, schema),
}, data)
}, schema, data)
}), nil
}

Expand Down Expand Up @@ -83,7 +83,7 @@ func (s *StoreWrapper) Update(apiContext *types.APIContext, schema *types.Schema

return apiContext.FilterObject(&types.QueryOptions{
Conditions: apiContext.SubContextAttributeProvider.Query(apiContext, schema),
}, data), nil
}, schema, data), nil
}

func (s *StoreWrapper) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) {
Expand All @@ -107,7 +107,7 @@ func validateGet(apiContext *types.APIContext, schema *types.Schema, id string)

if apiContext.Filter(&types.QueryOptions{
Conditions: apiContext.SubContextAttributeProvider.Query(apiContext, schema),
}, existing) == nil {
}, schema, existing) == nil {
return httperror.NewAPIError(httperror.NotFound, "failed to find "+id)
}

Expand Down
27 changes: 18 additions & 9 deletions types/condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,35 +39,44 @@ type QueryCondition struct {
left, right *QueryCondition
}

func (q *QueryCondition) Valid(data map[string]interface{}) bool {
func (q *QueryCondition) Valid(schema *Schema, data map[string]interface{}) bool {
switch q.conditionType {
case CondAnd:
if q.left == nil || q.right == nil {
return false
}
return q.left.Valid(data) && q.right.Valid(data)
return q.left.Valid(schema, data) && q.right.Valid(schema, data)
case CondOr:
if q.left == nil || q.right == nil {
return false
}
return q.left.Valid(data) || q.right.Valid(data)
return q.left.Valid(schema, data) || q.right.Valid(schema, data)
case CondEQ:
return q.Value == convert.ToString(data[q.Field])
return q.Value == convert.ToString(valueOrDefault(schema, data, q))
case CondNE:
return q.Value != convert.ToString(data[q.Field])
return q.Value != convert.ToString(valueOrDefault(schema, data, q))
case CondIn:
return q.Values[convert.ToString(data[q.Field])]
return q.Values[convert.ToString(valueOrDefault(schema, data, q))]
case CondNotIn:
return !q.Values[convert.ToString(data[q.Field])]
return !q.Values[convert.ToString(valueOrDefault(schema, data, q))]
case CondNotNull:
return convert.ToString(data[q.Field]) != ""
return convert.ToString(valueOrDefault(schema, data, q)) != ""
case CondNull:
return convert.ToString(data[q.Field]) == ""
return convert.ToString(valueOrDefault(schema, data, q)) == ""
}

return false
}

func valueOrDefault(schema *Schema, data map[string]interface{}, q *QueryCondition) interface{} {
value := data[q.Field]
if value == nil {
value = schema.ResourceFields[q.Field].Default
}

return value
}

func (q *QueryCondition) ToCondition() Condition {
cond := Condition{
Modifier: q.conditionType.Name,
Expand Down
16 changes: 8 additions & 8 deletions types/server_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ type ActionHandler func(actionName string, action *Action, request *APIContext)

type RequestHandler func(request *APIContext, next RequestHandler) error

type QueryFilter func(opts *QueryOptions, data []map[string]interface{}) []map[string]interface{}
type QueryFilter func(opts *QueryOptions, schema *Schema, data []map[string]interface{}) []map[string]interface{}

type Validator func(request *APIContext, schema *Schema, data map[string]interface{}) error

Expand Down Expand Up @@ -127,25 +127,25 @@ func (r *APIContext) WriteResponse(code int, obj interface{}) {
r.ResponseWriter.Write(r, code, obj)
}

func (r *APIContext) FilterList(opts *QueryOptions, obj []map[string]interface{}) []map[string]interface{} {
return r.QueryFilter(opts, obj)
func (r *APIContext) FilterList(opts *QueryOptions, schema *Schema, obj []map[string]interface{}) []map[string]interface{} {
return r.QueryFilter(opts, schema, obj)
}

func (r *APIContext) FilterObject(opts *QueryOptions, obj map[string]interface{}) map[string]interface{} {
func (r *APIContext) FilterObject(opts *QueryOptions, schema *Schema, obj map[string]interface{}) map[string]interface{} {
opts.Pagination = nil
result := r.QueryFilter(opts, []map[string]interface{}{obj})
result := r.QueryFilter(opts, schema, []map[string]interface{}{obj})
if len(result) == 0 {
return nil
}
return result[0]
}

func (r *APIContext) Filter(opts *QueryOptions, obj interface{}) interface{} {
func (r *APIContext) Filter(opts *QueryOptions, schema *Schema, obj interface{}) interface{} {
switch v := obj.(type) {
case []map[string]interface{}:
return r.FilterList(opts, v)
return r.FilterList(opts, schema, v)
case map[string]interface{}:
return r.FilterObject(opts, v)
return r.FilterObject(opts, schema, v)
}

return nil
Expand Down

0 comments on commit 7fed25b

Please sign in to comment.