diff --git a/pkg/migrate/README.adoc b/pkg/migrate/README.adoc index e421d789a..9d91673af 100644 --- a/pkg/migrate/README.adoc +++ b/pkg/migrate/README.adoc @@ -176,7 +176,8 @@ 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`. +* current cell -- `cell`, +* current row -- `row`; access cell by it's name -- eg. `row.FirstName + row.LastName`. The following example will remove the decimal point from every `sys_rating` in the given source. diff --git a/pkg/migrate/types/eval.go b/pkg/migrate/types/eval.go index b2362a378..dd691ebf4 100644 --- a/pkg/migrate/types/eval.go +++ b/pkg/migrate/types/eval.go @@ -3,15 +3,17 @@ package types import ( "fmt" "strconv" + "time" "github.com/PaesslerAG/gval" ) // generates a simple gval language to be used within the migration -func exprs() gval.Language { +func Exprs() gval.Language { return gval.NewLanguage( gval.JSON(), gval.Arithmetic(), + gval.PropositionalLogic(), gval.Function("numFmt", func(number, format string) (string, error) { nn, err := strconv.ParseFloat(number, 64) @@ -21,5 +23,25 @@ func exprs() gval.Language { return fmt.Sprintf(format, nn), nil }), + + gval.Function("fFmt", func(number float64, format string) (string, error) { + return fmt.Sprintf(format, number), nil + }), + + // diff between two dates in seconds + gval.Function("dateDiff", func(d1, d2 string) (float64, error) { + t1, err := time.Parse(SfDateTime, d1) + if err != nil { + return 0, err + } + + t2, err := time.Parse(SfDateTime, d2) + if err != nil { + return 0, err + } + + dr := t2.Sub(t1) + return dr.Seconds(), nil + }), ) } diff --git a/pkg/migrate/types/node.go b/pkg/migrate/types/node.go index 60cd2e5af..469598104 100644 --- a/pkg/migrate/types/node.go +++ b/pkg/migrate/types/node.go @@ -397,7 +397,7 @@ func importNodeSource(n *Node, users map[string]uint64, repo repository.RecordRe return r } - lng := exprs() + lng := Exprs() for { looper: @@ -417,6 +417,12 @@ func importNodeSource(n *Node, users map[string]uint64, repo repository.RecordRe } vals := types.RecordValueSet{} + + row := map[string]string{} + for i, h := range n.Header { + row[h] = record[i] + } + for i, h := range n.Header { var values []string val := record[i] @@ -564,7 +570,7 @@ func importNodeSource(n *Node, users map[string]uint64, repo repository.RecordRe return nil, err } - v, err = ev.EvalString(context.Background(), map[string]interface{}{"cell": v}) + v, err = ev.EvalString(context.Background(), map[string]interface{}{"cell": v, "row": row}) if err != nil { return nil, err }