// match: Match a simple pattern match and return matched value // // given input: // {"score_value":24,"event_click":true} // // match("score_") => {"value":24} // match("amount_") => false // match("event_") => {"click":true} // func Match(ctx expr.EvalContext, items ...value.Value) (value.MapValue, bool) { //u.Debugf("Match(): %T %v", item, item) mv := make(map[string]interface{}) for _, item := range items { switch node := item.(type) { case value.StringValue: matchKey := node.Val() for rowKey, val := range ctx.Row() { if strings.HasPrefix(rowKey, matchKey) && val != nil { newKey := strings.Replace(rowKey, matchKey, "", 1) if newKey != "" { mv[newKey] = val } } } default: u.Warnf("unsuported key type: %T %v", item, item) } } if len(mv) > 0 { //u.Infof("found new: %v", mv) return value.NewMapValue(mv), true } //u.Warnf("could not find key: %T %v", item, item) return value.EmptyMapValue, false }
// Map() Create a map from two values. If the right side value is nil // then does not evaluate // // Map(left, right) => map[string]value{left:right} // func MapFunc(ctx expr.EvalContext, lv, rv value.Value) (value.MapValue, bool) { if lv.Err() || rv.Err() { return value.EmptyMapValue, false } if lv.Nil() || rv.Nil() { return value.EmptyMapValue, false } return value.NewMapValue(map[string]interface{}{lv.ToString(): rv.Value()}), true }
func TestStructWrapper(t *testing.T) { t1, _ := dateparse.ParseAny("12/18/2015") tr := true user := &User{ Name: "Yoda", Created: t1, Updated: &t1, Authenticated: true, HasSession: &tr, Roles: []string{"admin", "api"}, BankAmount: 55.5, } readers := []expr.ContextReader{ datasource.NewContextWrapper(user), datasource.NewContextSimpleNative(map[string]interface{}{ "str1": "str1", "int1": 1, "t1": t1, "Name": "notyoda", }), } nc := datasource.NewNestedContextReader(readers, time.Now()) expected := value.NewMapValue(map[string]interface{}{ "str1": "str1", "int1": 1, "Name": "Yoda", "Authenticated": true, "bankamount": 55.5, "FullName": "Yoda, Jedi", "Roles": []string{"admin", "api"}, }) for k, v := range expected.Val() { //u.Infof("k:%v v:%#v", k, v) checkval(t, nc, k, v) } }
// TODO: {`any(0)`, value.BoolValueFalse}, {`any("value")`, value.BoolValueTrue}, {`any(event)`, value.BoolValueTrue}, {`any(notrealfield)`, value.BoolValueFalse}, {`all("Apple")`, value.BoolValueTrue}, {`all("Apple")`, value.BoolValueTrue}, {`all("Apple",event)`, value.BoolValueTrue}, {`all("Apple",event,true)`, value.BoolValueTrue}, {`all("Apple",event)`, value.BoolValueTrue}, {`all("Linux",true,not_a_realfield)`, value.BoolValueFalse}, {`all("Linux",false)`, value.BoolValueFalse}, {`all("Linux","")`, value.BoolValueFalse}, {`all("Linux",notreal)`, value.BoolValueFalse}, {`match("score_")`, value.NewMapValue(map[string]interface{}{"amount": "22"})}, {`match("score_","tag_")`, value.NewMapValue(map[string]interface{}{"amount": "22", "name": "bob"})}, {`match("nonfield_")`, value.ErrValue}, {`email("*****@*****.**")`, value.NewStringValue("*****@*****.**")}, {`email("Bob <bob>")`, value.ErrValue}, {`email("Bob <*****@*****.**>")`, value.NewStringValue("*****@*****.**")}, {`oneof(not_a_field, email("Bob <*****@*****.**>"))`, value.NewStringValue("*****@*****.**")}, {`oneof(email, email(not_a_field))`, value.NewStringValue("*****@*****.**")}, {`oneof(email, email(not_a_field)) NOT IN ("a","b",10, 4.5) `, value.NewBoolValue(true)}, {`oneof(email, email(not_a_field)) IN ("*****@*****.**","b",10, 4.5) `, value.NewBoolValue(true)}, {`oneof(email, email(not_a_field)) IN ("b",10, 4.5) `, value.NewBoolValue(false)}, {`emailname("Bob<*****@*****.**>")`, value.NewStringValue("Bob")},
// FilterFunc Filter out Values that match specified list of match filter criteria // // - Operates on MapValue (map[string]interface{}), StringsValue ([]string), or string // - takes N Filter Criteria // - supports Matching: "filter*" // matches "filter_x", "filterstuff" // // -- Filter a map of values by key to remove certain keys // filter(match("topic_"),key_to_filter, key2_to_filter) => {"goodkey": 22}, true // // -- Filter out VALUES (not keys) from a list of []string{} for a specific value // filter(split("apples,oranges",","),"ora*") => ["apples"], true // // -- Filter out values for single strings // filter("apples","app*") => []string{}, true // func FilterFunc(ctx expr.EvalContext, val value.Value, filterVals ...value.Value) (value.Value, bool) { filters := FiltersFromArgs(filterVals) //u.Debugf("Filter(): %T:%v filters:%v", val, val, filters) switch val := val.(type) { case value.MapValue: mv := make(map[string]interface{}) for rowKey, v := range val.Val() { filteredOut := false for _, filter := range filters { if strings.Contains(filter, "*") { match, _ := glob.Match(filter, rowKey) if match { filteredOut = true break } } else { if strings.HasPrefix(rowKey, filter) && v != nil { filteredOut = true break } } } if !filteredOut { mv[rowKey] = v.Value() } } return value.NewMapValue(mv), true case value.StringValue: anyMatches := false for _, filter := range filters { if strings.Contains(filter, "*") { match, _ := glob.Match(filter, val.Val()) if match { anyMatches = true break } } else { if strings.HasPrefix(val.Val(), filter) { anyMatches = true break } } } if anyMatches { return value.NilValueVal, true } return val, true case value.StringsValue: lv := make([]string, 0, val.Len()) for _, sv := range val.Val() { filteredOut := false for _, filter := range filters { if strings.Contains(filter, "*") { match, _ := glob.Match(filter, sv) if match { filteredOut = true break } } else { if strings.HasPrefix(sv, filter) && sv != "" { filteredOut = true break } } } if !filteredOut { lv = append(lv, sv) } } return value.NewStringsValue(lv), true default: u.Warnf("unsuported key type: %T %v", val, val) } //u.Warnf("could not find key: %T %v", item, item) return nil, false }
// TODO: {`any(0)`, value.BoolValueFalse}, {`any("value")`, value.BoolValueTrue}, {`any(event)`, value.BoolValueTrue}, {`any(notrealfield)`, value.BoolValueFalse}, {`all("Apple")`, value.BoolValueTrue}, {`all("Apple")`, value.BoolValueTrue}, {`all("Apple",event)`, value.BoolValueTrue}, {`all("Apple",event,true)`, value.BoolValueTrue}, {`all("Apple",event)`, value.BoolValueTrue}, {`all("Linux",true,not_a_realfield)`, value.BoolValueFalse}, {`all("Linux",false)`, value.BoolValueFalse}, {`all("Linux","")`, value.BoolValueFalse}, {`all("Linux",notreal)`, value.BoolValueFalse}, {`match("score_")`, value.NewMapValue(map[string]interface{}{"amount": "22"})}, {`match("nonfield_")`, value.ErrValue}, {`email("*****@*****.**")`, value.NewStringValue("*****@*****.**")}, {`email("Bob <bob>")`, value.ErrValue}, {`email("Bob <*****@*****.**>")`, value.NewStringValue("*****@*****.**")}, {`oneof(not_a_field, email("Bob <*****@*****.**>"))`, value.NewStringValue("*****@*****.**")}, {`oneof(email, email(not_a_field))`, value.NewStringValue("*****@*****.**")}, {`emailname("Bob<*****@*****.**>")`, value.NewStringValue("Bob")}, {`emaildomain("Bob<*****@*****.**>")`, value.NewStringValue("gmail.com")}, {`host("https://www.Google.com/search?q=golang")`, value.NewStringValue("www.google.com")}, {`host("www.Google.com/?q=golang")`, value.NewStringValue("www.google.com")}, //{`host("notvalid")`, value.NewStringValue("notvalid")},