1
0
mirror of https://github.com/rancher/norman.git synced 2025-04-28 11:24:47 +00:00
norman/types/condition.go
Nathan Jenan 7fed8b17a8 Filter resources on default fields
This change gives norman the ability to filter api requests based on the
default value of fields.  Before, it would filter on the actual data in
the resource, and then apply default values to the resource before
returning.

Issue:
https://github.com/rancher/rancher/issues/13418
2018-05-16 10:15:34 -07:00

122 lines
2.9 KiB
Go

package types
import (
"github.com/rancher/norman/types/convert"
)
var (
CondEQ = QueryConditionType{ModifierEQ, 1}
CondNE = QueryConditionType{ModifierNE, 1}
CondNull = QueryConditionType{ModifierNull, 0}
CondNotNull = QueryConditionType{ModifierNotNull, 0}
CondIn = QueryConditionType{ModifierIn, -1}
CondNotIn = QueryConditionType{ModifierNotIn, -1}
CondOr = QueryConditionType{ModifierType("or"), 1}
CondAnd = QueryConditionType{ModifierType("and"), 1}
mods = map[ModifierType]QueryConditionType{
CondEQ.Name: CondEQ,
CondNE.Name: CondNE,
CondNull.Name: CondNull,
CondNotNull.Name: CondNotNull,
CondIn.Name: CondIn,
CondNotIn.Name: CondNotIn,
CondOr.Name: CondOr,
CondAnd.Name: CondAnd,
}
)
type QueryConditionType struct {
Name ModifierType
Args int
}
type QueryCondition struct {
Field string
Value string
Values map[string]bool
conditionType QueryConditionType
left, right *QueryCondition
}
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(schema, data) && q.right.Valid(schema, data)
case CondOr:
if q.left == nil || q.right == nil {
return false
}
return q.left.Valid(schema, data) || q.right.Valid(schema, data)
case CondEQ:
return q.Value == convert.ToString(valueOrDefault(schema, data, q))
case CondNE:
return q.Value != convert.ToString(valueOrDefault(schema, data, q))
case CondIn:
return q.Values[convert.ToString(valueOrDefault(schema, data, q))]
case CondNotIn:
return !q.Values[convert.ToString(valueOrDefault(schema, data, q))]
case CondNotNull:
return convert.ToString(valueOrDefault(schema, data, q)) != ""
case CondNull:
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,
}
if q.conditionType.Args == 1 {
cond.Value = q.Value
} else if q.conditionType.Args == -1 {
stringValues := []string{}
for val := range q.Values {
stringValues = append(stringValues, val)
}
cond.Value = stringValues
}
return cond
}
func ValidMod(mod ModifierType) bool {
_, ok := mods[mod]
return ok
}
func EQ(key, value string) *QueryCondition {
return NewConditionFromString(key, ModifierEQ, value)
}
func NewConditionFromString(field string, mod ModifierType, values ...string) *QueryCondition {
q := &QueryCondition{
Field: field,
conditionType: mods[mod],
Values: map[string]bool{},
}
for i, value := range values {
if i == 0 {
q.Value = value
}
q.Values[value] = true
}
return q
}