Skip to content

Commit

Permalink
feat: function join support array (#336)
Browse files Browse the repository at this point in the history
Signed-off-by: delu <delu.xu@linkall.com>

Signed-off-by: delu <delu.xu@linkall.com>
  • Loading branch information
xdlbdy authored Dec 12, 2022
1 parent 201e042 commit f6e6f9c
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 16 deletions.
4 changes: 2 additions & 2 deletions internal/primitive/transform/action/string_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ import (
"github.com/linkall-labs/vanus/internal/primitive/transform/function"
)

// ["join", "toKey", "separator","key1","key2"].
// ["join", "toKey", "separator","key1",...].
func newJoinAction() Action {
return &commonAction{
fixedArgs: []arg.TypeList{arg.EventList, arg.All, arg.All, arg.All},
fixedArgs: []arg.TypeList{arg.EventList, arg.All, arg.All},
variadicArg: arg.All,
fn: function.JoinFunction,
}
Expand Down
49 changes: 41 additions & 8 deletions internal/primitive/transform/action/string_action_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,53 @@ import (
"testing"

"github.com/linkall-labs/vanus/internal/primitive/transform/context"

. "github.com/smartystreets/goconvey/convey"
)

func TestStringAction(t *testing.T) {
Convey("test join action", t, func() {
a, err := NewAction([]interface{}{newJoinAction().Name(), "$.test", ",", "abc", "123"})
So(err, ShouldBeNil)
e := newEvent()
err = a.Execute(&context.EventContext{
Event: e,
eventCtx := &context.EventContext{
Event: newEvent(),
Data: map[string]interface{}{
"array": []map[string]interface{}{
{"key1": "value1"},
{"key1": "value11"},
{"key1": "value111"},
},
},
}
Convey("test string", func() {
Convey("test one param", func() {
a, err := NewAction([]interface{}{newJoinAction().Name(), "$.test1", ",", "abc"})
So(err, ShouldBeNil)
err = a.Execute(eventCtx)
So(err, ShouldBeNil)
So(eventCtx.Event.Extensions()["test1"], ShouldEqual, "abc")
})
Convey("test many param", func() {
a, err := NewAction([]interface{}{newJoinAction().Name(), "$.test2", ",", "abc", "123"})
So(err, ShouldBeNil)
err = a.Execute(eventCtx)
So(err, ShouldBeNil)
So(eventCtx.Event.Extensions()["test2"], ShouldEqual, "abc,123")
})
})
Convey("test string array", func() {
Convey("test one param", func() {
a, err := NewAction([]interface{}{newJoinAction().Name(), "$.array1", ",", "$.data.array[:].key1"})
So(err, ShouldBeNil)
err = a.Execute(eventCtx)
So(err, ShouldBeNil)
So(eventCtx.Event.Extensions()["array1"], ShouldEqual, "value1,value11,value111")
})
Convey("test many mixture param", func() {
a, err := NewAction([]interface{}{newJoinAction().Name(), "$.array2", ",", "$.data.array[:].key1", "$.source", "abc"})
So(err, ShouldBeNil)
err = a.Execute(eventCtx)
So(err, ShouldBeNil)
So(eventCtx.Event.Extensions()["array2"], ShouldEqual, "value1,value11,value111,testSource,abc")
})
})
So(err, ShouldBeNil)
So(e.Extensions()["test"], ShouldEqual, "abc,123")
})
Convey("test upper", t, func() {
a, err := NewAction([]interface{}{newUpperAction().Name(), "$.test"})
Expand Down
16 changes: 16 additions & 0 deletions internal/primitive/transform/function/cast.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,22 @@ func Cast(val interface{}, target Type) (interface{}, error) {
return false, fmt.Errorf("cannot cast String to Bool, actual value: %v", val)
}
return false, fmt.Errorf("undefined cast from %v to %v", TypeFromVal(val), target)
case StringArray:
switch value := val.(type) {
case string:
return []string{value}, nil
case []interface{}:
stringArr := make([]string, len(value))
for i := range value {
v, err := Cast(value[i], String)
if err != nil {
return nil, err
}
str, _ := v.(string)
stringArr[i] = str
}
return stringArr, nil
}
}

// AnyType doesn't need casting
Expand Down
12 changes: 6 additions & 6 deletions internal/primitive/transform/function/strings_functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ import "strings"

var JoinFunction = function{
name: "JOIN",
fixedArgs: []Type{String, String, String},
variadicArgs: TypePtr(String),
fixedArgs: []Type{String, StringArray},
variadicArgs: TypePtr(StringArray),
fn: func(args []interface{}) (interface{}, error) {
separator, _ := args[0].(string)
sep, _ := args[0].(string)
var sb strings.Builder
for i := 1; i < len(args)-1; i++ {
sb.WriteString(args[i].(string))
sb.WriteString(separator)
sb.WriteString(strings.Join(args[i].([]string), sep))
sb.WriteString(sep)
}
sb.WriteString(args[len(args)-1].(string))
sb.WriteString(strings.Join(args[len(args)-1].([]string), sep))
return sb.String(), nil
},
}
Expand Down
5 changes: 5 additions & 0 deletions internal/primitive/transform/function/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const (
Bool
Object
Array
StringArray
Any
)

Expand All @@ -39,6 +40,8 @@ func (t Type) String() string {
return "array"
case Any:
return "any"
case StringArray:
return "stringArray"
}
return "unknown"
}
Expand All @@ -61,6 +64,8 @@ func TypeFromVal(val interface{}) Type {
return Bool
case map[string]interface{}:
return Object
case []string:
return StringArray
case []interface{}:
return Array
}
Expand Down

0 comments on commit f6e6f9c

Please sign in to comment.