2017-11-11 04:44:02 +00:00
|
|
|
package types
|
|
|
|
|
2017-11-21 20:46:30 +00:00
|
|
|
import (
|
|
|
|
"github.com/rancher/norman/types/convert"
|
|
|
|
)
|
2017-11-11 04:44:02 +00:00
|
|
|
|
2017-11-21 20:46:30 +00:00
|
|
|
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,
|
2017-11-11 04:44:02 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
type QueryConditionType struct {
|
2017-11-21 20:46:30 +00:00
|
|
|
Name ModifierType
|
2017-11-11 04:44:02 +00:00
|
|
|
Args int
|
|
|
|
}
|
|
|
|
|
|
|
|
type QueryCondition struct {
|
|
|
|
Field string
|
2017-11-21 20:46:30 +00:00
|
|
|
Value string
|
|
|
|
Values map[string]bool
|
2017-11-11 04:44:02 +00:00
|
|
|
conditionType QueryConditionType
|
|
|
|
left, right *QueryCondition
|
|
|
|
}
|
|
|
|
|
2018-05-15 22:24:07 +00:00
|
|
|
func (q *QueryCondition) Valid(schema *Schema, data map[string]interface{}) bool {
|
2017-11-21 20:46:30 +00:00
|
|
|
switch q.conditionType {
|
|
|
|
case CondAnd:
|
|
|
|
if q.left == nil || q.right == nil {
|
|
|
|
return false
|
|
|
|
}
|
2018-05-15 22:24:07 +00:00
|
|
|
return q.left.Valid(schema, data) && q.right.Valid(schema, data)
|
2017-11-21 20:46:30 +00:00
|
|
|
case CondOr:
|
|
|
|
if q.left == nil || q.right == nil {
|
|
|
|
return false
|
|
|
|
}
|
2018-05-15 22:24:07 +00:00
|
|
|
return q.left.Valid(schema, data) || q.right.Valid(schema, data)
|
2017-11-21 20:46:30 +00:00
|
|
|
case CondEQ:
|
2018-05-15 22:24:07 +00:00
|
|
|
return q.Value == convert.ToString(valueOrDefault(schema, data, q))
|
2017-11-21 20:46:30 +00:00
|
|
|
case CondNE:
|
2018-05-15 22:24:07 +00:00
|
|
|
return q.Value != convert.ToString(valueOrDefault(schema, data, q))
|
2017-11-21 20:46:30 +00:00
|
|
|
case CondIn:
|
2018-05-15 22:24:07 +00:00
|
|
|
return q.Values[convert.ToString(valueOrDefault(schema, data, q))]
|
2017-11-21 20:46:30 +00:00
|
|
|
case CondNotIn:
|
2018-05-15 22:24:07 +00:00
|
|
|
return !q.Values[convert.ToString(valueOrDefault(schema, data, q))]
|
2017-11-21 20:46:30 +00:00
|
|
|
case CondNotNull:
|
2018-05-15 22:24:07 +00:00
|
|
|
return convert.ToString(valueOrDefault(schema, data, q)) != ""
|
2017-11-21 20:46:30 +00:00
|
|
|
case CondNull:
|
2018-05-15 22:24:07 +00:00
|
|
|
return convert.ToString(valueOrDefault(schema, data, q)) == ""
|
2017-11-21 20:46:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2018-05-15 22:24:07 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2017-11-11 04:44:02 +00:00
|
|
|
func (q *QueryCondition) ToCondition() Condition {
|
|
|
|
cond := Condition{
|
|
|
|
Modifier: q.conditionType.Name,
|
|
|
|
}
|
2017-11-21 20:46:30 +00:00
|
|
|
if q.conditionType.Args == 1 {
|
|
|
|
cond.Value = q.Value
|
2017-11-11 04:44:02 +00:00
|
|
|
} else if q.conditionType.Args == -1 {
|
2017-11-21 20:46:30 +00:00
|
|
|
stringValues := []string{}
|
|
|
|
for val := range q.Values {
|
|
|
|
stringValues = append(stringValues, val)
|
|
|
|
}
|
|
|
|
cond.Value = stringValues
|
2017-11-11 04:44:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return cond
|
|
|
|
}
|
|
|
|
|
2017-11-21 20:46:30 +00:00
|
|
|
func ValidMod(mod ModifierType) bool {
|
2017-11-11 04:44:02 +00:00
|
|
|
_, ok := mods[mod]
|
|
|
|
return ok
|
|
|
|
}
|
|
|
|
|
2018-01-18 05:29:23 +00:00
|
|
|
func EQ(key, value string) *QueryCondition {
|
|
|
|
return NewConditionFromString(key, ModifierEQ, value)
|
|
|
|
}
|
|
|
|
|
2017-11-21 20:46:30 +00:00
|
|
|
func NewConditionFromString(field string, mod ModifierType, values ...string) *QueryCondition {
|
|
|
|
q := &QueryCondition{
|
2017-11-11 04:44:02 +00:00
|
|
|
Field: field,
|
|
|
|
conditionType: mods[mod],
|
2017-11-21 20:46:30 +00:00
|
|
|
Values: map[string]bool{},
|
2017-11-11 04:44:02 +00:00
|
|
|
}
|
|
|
|
|
2017-11-21 20:46:30 +00:00
|
|
|
for i, value := range values {
|
|
|
|
if i == 0 {
|
|
|
|
q.Value = value
|
|
|
|
}
|
|
|
|
q.Values[value] = true
|
2017-11-11 04:44:02 +00:00
|
|
|
}
|
|
|
|
|
2017-11-21 20:46:30 +00:00
|
|
|
return q
|
2017-11-11 04:44:02 +00:00
|
|
|
}
|