Add support for expression evaluation
This commit is contained in:
parent
8e31d43c29
commit
d034197092
2
go.mod
2
go.mod
@ -8,7 +8,7 @@ require (
|
||||
github.com/766b/chi-prometheus v0.0.0-20180509160047-46ac2b31aa30
|
||||
github.com/99designs/basicauth-go v0.0.0-20160802081356-2a93ba0f464d
|
||||
github.com/Masterminds/squirrel v1.1.1-0.20191017225151-12f2162c8d8d
|
||||
github.com/PaesslerAG/gval v1.0.1 // indirect
|
||||
github.com/PaesslerAG/gval v1.0.1
|
||||
github.com/PaesslerAG/jsonpath v0.1.1 // indirect
|
||||
github.com/SentimensRG/ctx v0.0.0-20180729130232-0bfd988c655d
|
||||
github.com/crusttech/go-oidc v0.0.0-20180918092017-982855dad3e1
|
||||
|
||||
@ -171,3 +171,20 @@ The following value mapping maps `sys_status` field's values; the left one into
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
The system also provides support for arbitrary mathematical expressions.
|
||||
If you wish to perform an expression, prefix the mapped value with `=EVL=`; for example `=EVL=numFmt(cell, \"%.0f\")`.
|
||||
|
||||
Variables:
|
||||
* current cell -- `cell`.
|
||||
|
||||
The following example will remove the decimal point from every `sys_rating` in the given source.
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"sys_rating": {
|
||||
"*": "=EVL=numFmt(cell, \"%.0f\")"
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
25
pkg/migrate/types/eval.go
Normal file
25
pkg/migrate/types/eval.go
Normal file
@ -0,0 +1,25 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/PaesslerAG/gval"
|
||||
)
|
||||
|
||||
// generates a simple gval language to be used within the migration
|
||||
func exprs() gval.Language {
|
||||
return gval.NewLanguage(
|
||||
gval.JSON(),
|
||||
gval.Arithmetic(),
|
||||
|
||||
gval.Function("numFmt", func(number, format string) (string, error) {
|
||||
nn, err := strconv.ParseFloat(number, 64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf(format, nn), nil
|
||||
}),
|
||||
)
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/csv"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -72,6 +73,10 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
evalPrefix = "=EVL="
|
||||
)
|
||||
|
||||
// helper, to determine if the two nodes are equal
|
||||
func (n *Node) Compare(to *Node) bool {
|
||||
return n.Name == to.Name && n.spliced == to.spliced
|
||||
@ -392,6 +397,8 @@ func importNodeSource(n *Node, users map[string]uint64, repo repository.RecordRe
|
||||
return r
|
||||
}
|
||||
|
||||
lng := exprs()
|
||||
|
||||
for {
|
||||
looper:
|
||||
record, err := n.Reader.Read()
|
||||
@ -526,10 +533,26 @@ func importNodeSource(n *Node, users map[string]uint64, repo repository.RecordRe
|
||||
|
||||
for i, v := range values {
|
||||
if fmp, ok := n.ValueMap[h]; ok {
|
||||
nvl := ""
|
||||
if mpv, ok := fmp[v]; ok {
|
||||
v = mpv
|
||||
nvl = mpv
|
||||
} else if mpv, ok := fmp["*"]; ok {
|
||||
v = mpv
|
||||
nvl = mpv
|
||||
}
|
||||
|
||||
if nvl != "" && strings.HasPrefix(nvl, evalPrefix) {
|
||||
opp := nvl[len(evalPrefix):len(nvl)]
|
||||
ev, err := lng.NewEvaluable(opp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v, err = ev.EvalString(context.Background(), map[string]interface{}{"cell": v})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if nvl != "" {
|
||||
v = nvl
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user