- Converted Tamarin script language to Risor - Added a "find" and "merge" method to the result set script type. - Added the ability to copy the table of results to the pasteboard by pressing C - Added the -q flag, which will run a query and display the results as a CSV file on the command line - Upgraded Go to 1.21 in Github actions - Fix issue with missing limits - Added the '-where' switch to the mark - Added the 'marked' function to the query expression. - Added a sampled time and count on the right-side of the mode line - Added the 'M' key binding to toggle the marked items - Started working on tab completion for 'sa' and 'da' commands - Added count and sample time to the right-side of the mode line - Added Ctrl+V to the prompt to paste the text of the pasteboard with all whitespace characters trimmed - Fixed failing unit tests
129 lines
3.5 KiB
Go
129 lines
3.5 KiB
Go
package queryexpr
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type nativeFunc func(ctx context.Context, args []exprValue) (exprValue, error)
|
|
|
|
var nativeFuncs = map[string]nativeFunc{
|
|
"size": func(ctx context.Context, args []exprValue) (exprValue, error) {
|
|
if len(args) != 1 {
|
|
return nil, InvalidArgumentNumberError{Name: "size", Expected: 1, Actual: len(args)}
|
|
}
|
|
|
|
var l int
|
|
switch t := args[0].(type) {
|
|
case stringExprValue:
|
|
l = len(t)
|
|
case mappableExprValue:
|
|
l = t.len()
|
|
case slicableExprValue:
|
|
l = t.len()
|
|
default:
|
|
return nil, errors.New("cannot take size of arg")
|
|
}
|
|
return int64ExprValue(l), nil
|
|
},
|
|
|
|
"range": func(ctx context.Context, args []exprValue) (exprValue, error) {
|
|
if len(args) != 2 {
|
|
return nil, InvalidArgumentNumberError{Name: "range", Expected: 2, Actual: len(args)}
|
|
}
|
|
|
|
xVal, isXNum := args[0].(numberableExprValue)
|
|
if !isXNum {
|
|
return nil, InvalidArgumentTypeError{Name: "range", ArgIndex: 0, Expected: "N"}
|
|
}
|
|
yVal, isYNum := args[1].(numberableExprValue)
|
|
if !isYNum {
|
|
return nil, InvalidArgumentTypeError{Name: "range", ArgIndex: 1, Expected: "N"}
|
|
}
|
|
|
|
xInt, _ := xVal.asBigFloat().Int64()
|
|
yInt, _ := yVal.asBigFloat().Int64()
|
|
xs := make([]exprValue, 0)
|
|
for x := xInt; x <= yInt; x++ {
|
|
xs = append(xs, int64ExprValue(x))
|
|
}
|
|
return listExprValue(xs), nil
|
|
},
|
|
|
|
"marked": func(ctx context.Context, args []exprValue) (exprValue, error) {
|
|
if len(args) != 1 {
|
|
return nil, InvalidArgumentNumberError{Name: "marked", Expected: 1, Actual: len(args)}
|
|
}
|
|
|
|
fieldName, ok := args[0].(stringableExprValue)
|
|
if !ok {
|
|
return nil, InvalidArgumentTypeError{Name: "marked", ArgIndex: 0, Expected: "S"}
|
|
}
|
|
|
|
rs := currentResultSetFromContext(ctx)
|
|
if rs == nil {
|
|
return listExprValue{}, nil
|
|
}
|
|
|
|
var items = []exprValue{}
|
|
for i, itm := range rs.Items() {
|
|
if !rs.Marked(i) {
|
|
continue
|
|
}
|
|
|
|
attr, hasAttr := itm[fieldName.asString()]
|
|
if !hasAttr {
|
|
continue
|
|
}
|
|
|
|
exprAttrValue, err := newExprValueFromAttributeValue(attr)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "marked(): item %d, attr %v", i, fieldName.asString())
|
|
}
|
|
|
|
items = append(items, exprAttrValue)
|
|
}
|
|
return listExprValue(items), nil
|
|
},
|
|
|
|
"_x_now": func(ctx context.Context, args []exprValue) (exprValue, error) {
|
|
now := timeSourceFromContext(ctx).now().Unix()
|
|
return int64ExprValue(now), nil
|
|
},
|
|
|
|
"_x_add": func(ctx context.Context, args []exprValue) (exprValue, error) {
|
|
if len(args) != 2 {
|
|
return nil, InvalidArgumentNumberError{Name: "_x_add", Expected: 2, Actual: len(args)}
|
|
}
|
|
|
|
xVal, isXNum := args[0].(numberableExprValue)
|
|
if !isXNum {
|
|
return nil, InvalidArgumentTypeError{Name: "_x_add", ArgIndex: 0, Expected: "N"}
|
|
}
|
|
yVal, isYNum := args[1].(numberableExprValue)
|
|
if !isYNum {
|
|
return nil, InvalidArgumentTypeError{Name: "_x_add", ArgIndex: 1, Expected: "N"}
|
|
}
|
|
|
|
return bigNumExprValue{num: xVal.asBigFloat().Add(xVal.asBigFloat(), yVal.asBigFloat())}, nil
|
|
},
|
|
|
|
"_x_concat": func(ctx context.Context, args []exprValue) (exprValue, error) {
|
|
if len(args) != 2 {
|
|
return nil, InvalidArgumentNumberError{Name: "_x_concat", Expected: 2, Actual: len(args)}
|
|
}
|
|
|
|
xVal, isXNum := args[0].(stringableExprValue)
|
|
if !isXNum {
|
|
return nil, InvalidArgumentTypeError{Name: "_x_concat", ArgIndex: 0, Expected: "S"}
|
|
}
|
|
yVal, isYNum := args[1].(stringableExprValue)
|
|
if !isYNum {
|
|
return nil, InvalidArgumentTypeError{Name: "_x_concat", ArgIndex: 1, Expected: "S"}
|
|
}
|
|
|
|
return stringExprValue(xVal.asString() + yVal.asString()), nil
|
|
},
|
|
}
|