From 112461fded0d7970817ce7bf476c4763922ad314 Mon Sep 17 00:00:00 2001 From: Cameron Moore Date: Mon, 26 Nov 2018 18:40:35 -0600 Subject: [PATCH] tpl/collections: Add float64 support to where Fixes #5466 --- tpl/collections/where.go | 66 ++++++++++++++++++------ tpl/collections/where_test.go | 94 +++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 15 deletions(-) diff --git a/tpl/collections/where.go b/tpl/collections/where.go index be5c8205b..859353ff0 100644 --- a/tpl/collections/where.go +++ b/tpl/collections/where.go @@ -79,9 +79,11 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error } var ivp, imvp *int64 + var fvp, fmvp *float64 var svp, smvp *string var slv, slmv interface{} var ima []int64 + var fma []float64 var sma []string if mv.Type() == v.Type() { switch v.Kind() { @@ -95,6 +97,11 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error svp = &sv smv := mv.String() smvp = &smv + case reflect.Float64: + fv := v.Float() + fvp = &fv + fmv := mv.Float() + fmvp = &fmv case reflect.Struct: switch v.Type() { case timeType: @@ -136,6 +143,14 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error sma = append(sma, aString) } } + case reflect.Float64: + fv := v.Float() + fvp = &fv + for i := 0; i < mv.Len(); i++ { + if aFloat, err := toFloat(mv.Index(i)); err == nil { + fma = append(fma, aFloat) + } + } case reflect.Struct: switch v.Type() { case timeType: @@ -153,52 +168,73 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error switch op { case "", "=", "==", "eq": - if ivp != nil && imvp != nil { + switch { + case ivp != nil && imvp != nil: return *ivp == *imvp, nil - } else if svp != nil && smvp != nil { + case svp != nil && smvp != nil: return *svp == *smvp, nil + case fvp != nil && fmvp != nil: + return *fvp == *fmvp, nil } case "!=", "<>", "ne": - if ivp != nil && imvp != nil { + switch { + case ivp != nil && imvp != nil: return *ivp != *imvp, nil - } else if svp != nil && smvp != nil { + case svp != nil && smvp != nil: return *svp != *smvp, nil + case fvp != nil && fmvp != nil: + return *fvp != *fmvp, nil } case ">=", "ge": - if ivp != nil && imvp != nil { + switch { + case ivp != nil && imvp != nil: return *ivp >= *imvp, nil - } else if svp != nil && smvp != nil { + case svp != nil && smvp != nil: return *svp >= *smvp, nil + case fvp != nil && fmvp != nil: + return *fvp >= *fmvp, nil } case ">", "gt": - if ivp != nil && imvp != nil { + switch { + case ivp != nil && imvp != nil: return *ivp > *imvp, nil - } else if svp != nil && smvp != nil { + case svp != nil && smvp != nil: return *svp > *smvp, nil + case fvp != nil && fmvp != nil: + return *fvp > *fmvp, nil } case "<=", "le": - if ivp != nil && imvp != nil { + switch { + case ivp != nil && imvp != nil: return *ivp <= *imvp, nil - } else if svp != nil && smvp != nil { + case svp != nil && smvp != nil: return *svp <= *smvp, nil + case fvp != nil && fmvp != nil: + return *fvp <= *fmvp, nil } case "<", "lt": - if ivp != nil && imvp != nil { + switch { + case ivp != nil && imvp != nil: return *ivp < *imvp, nil - } else if svp != nil && smvp != nil { + case svp != nil && smvp != nil: return *svp < *smvp, nil + case fvp != nil && fmvp != nil: + return *fvp < *fmvp, nil } case "in", "not in": var r bool - if ivp != nil && len(ima) > 0 { + switch { + case ivp != nil && len(ima) > 0: r = ns.In(ima, *ivp) - } else if svp != nil { + case fvp != nil && len(fma) > 0: + r = ns.In(fma, *fvp) + case svp != nil: if len(sma) > 0 { r = ns.In(sma, *svp) } else if smvp != nil { r = ns.In(*smvp, *svp) } - } else { + default: return false, nil } if op == "not in" { diff --git a/tpl/collections/where_test.go b/tpl/collections/where_test.go index e70283778..bf3d5011c 100644 --- a/tpl/collections/where_test.go +++ b/tpl/collections/where_test.go @@ -63,6 +63,48 @@ func TestWhere(t *testing.T) { {"a": 3, "b": 4}, }, }, + { + seq: []map[string]float64{ + {"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "x": 4}, + }, + key: "b", match: 4.0, + expect: []map[string]float64{{"a": 3, "b": 4}}, + }, + { + seq: []map[string]float64{ + {"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "x": 4}, + }, + key: "b", match: 4.0, op: "!=", + expect: []map[string]float64{{"a": 1, "b": 2}, {"a": 5, "x": 4}}, + }, + { + seq: []map[string]float64{ + {"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "x": 4}, + }, + key: "b", match: 4.0, op: "<", + expect: []map[string]float64{{"a": 1, "b": 2}}, + }, + { + seq: []map[string]float64{ + {"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "x": 4}, + }, + key: "b", match: 4.0, op: "<=", + expect: []map[string]float64{{"a": 1, "b": 2}, {"a": 3, "b": 4}}, + }, + { + seq: []map[string]float64{ + {"a": 1, "b": 2}, {"a": 3, "b": 3}, {"a": 5, "x": 4}, + }, + key: "b", match: 2.0, op: ">", + expect: []map[string]float64{{"a": 3, "b": 3}}, + }, + { + seq: []map[string]float64{ + {"a": 1, "b": 2}, {"a": 3, "b": 3}, {"a": 5, "x": 4}, + }, + key: "b", match: 2.0, op: ">=", + expect: []map[string]float64{{"a": 1, "b": 2}, {"a": 3, "b": 3}}, + }, { seq: []TstX{ {A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"}, @@ -180,6 +222,15 @@ func TestWhere(t *testing.T) { {"a": 3, "b": 4}, {"a": 5, "b": 6}, }, }, + { + seq: []map[string]float64{ + {"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6}, + }, + key: "b", op: ">", match: 3.0, + expect: []map[string]float64{ + {"a": 3, "b": 4}, {"a": 5, "b": 6}, + }, + }, { seq: []TstX{ {A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"}, @@ -198,6 +249,15 @@ func TestWhere(t *testing.T) { {"a": 3, "b": 4}, }, }, + { + seq: []map[string]float64{ + {"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6}, + }, + key: "b", op: "in", match: []float64{3, 4, 5}, + expect: []map[string]float64{ + {"a": 3, "b": 4}, + }, + }, { seq: []map[string][]string{ {"a": []string{"A", "B", "C"}, "b": []string{"D", "E", "F"}}, {"a": []string{"G", "H", "I"}, "b": []string{"J", "K", "L"}}, {"a": []string{"M", "N", "O"}, "b": []string{"P", "Q", "R"}}, @@ -279,6 +339,15 @@ func TestWhere(t *testing.T) { {"a": 3, "b": 4}, }, }, + { + seq: []map[string]float64{ + {"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6}, + }, + key: "b", op: "in", match: ns.Slice(3.0, 4.0, 5.0), + expect: []map[string]float64{ + {"a": 3, "b": 4}, + }, + }, { seq: []map[string]time.Time{ {"a": d1, "b": d2}, {"a": d3, "b": d4}, {"a": d5, "b": d6}, @@ -331,6 +400,31 @@ func TestWhere(t *testing.T) { key: "b", op: ">", match: nil, expect: []map[string]int{}, }, + { + seq: []map[string]float64{ + {"a": 1, "b": 2}, {"a": 3}, {"a": 5, "b": 6}, + }, + key: "b", op: "", match: nil, + expect: []map[string]float64{ + {"a": 3}, + }, + }, + { + seq: []map[string]float64{ + {"a": 1, "b": 2}, {"a": 3}, {"a": 5, "b": 6}, + }, + key: "b", op: "!=", match: nil, + expect: []map[string]float64{ + {"a": 1, "b": 2}, {"a": 5, "b": 6}, + }, + }, + { + seq: []map[string]float64{ + {"a": 1, "b": 2}, {"a": 3}, {"a": 5, "b": 6}, + }, + key: "b", op: ">", match: nil, + expect: []map[string]float64{}, + }, { seq: []map[string]bool{ {"a": true, "b": false}, {"c": true, "b": true}, {"d": true, "b": false},