- 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
146 lines
4.2 KiB
Go
146 lines
4.2 KiB
Go
package scriptmanager
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
|
"github.com/pkg/errors"
|
|
"github.com/risor-io/risor/object"
|
|
)
|
|
|
|
type sessionModule struct {
|
|
sessionService SessionService
|
|
}
|
|
|
|
func (um *sessionModule) query(ctx context.Context, args ...object.Object) object.Object {
|
|
if len(args) == 0 || len(args) > 2 {
|
|
return object.Errorf("type error: session.query takes either 1 or 2 arguments (%d given)", len(args))
|
|
}
|
|
|
|
var options QueryOptions
|
|
|
|
expr, objErr := object.AsString(args[0])
|
|
if objErr != nil {
|
|
return objErr
|
|
}
|
|
|
|
if len(args) == 2 {
|
|
objMap, objErr := object.AsMap(args[1])
|
|
if objErr != nil {
|
|
return objErr
|
|
}
|
|
|
|
// Table name
|
|
if val := objMap.Get("table"); val != object.Nil && val.IsTruthy() {
|
|
switch tv := val.(type) {
|
|
case *object.String:
|
|
options.TableName = tv.Value()
|
|
case *tableProxy:
|
|
options.TableName = tv.table.Name
|
|
default:
|
|
return object.Errorf("type error: query option 'table' must be either a string or table")
|
|
}
|
|
}
|
|
|
|
// Index name
|
|
if val, isStr := objMap.Get("index").(*object.String); isStr {
|
|
options.IndexName = val.Value()
|
|
}
|
|
|
|
// Placeholders
|
|
if argsVal, isArgsValMap := objMap.Get("args").(*object.Map); isArgsValMap {
|
|
options.NamePlaceholders = make(map[string]string)
|
|
options.ValuePlaceholders = make(map[string]types.AttributeValue)
|
|
|
|
for k, val := range argsVal.Value() {
|
|
switch v := val.(type) {
|
|
case *object.String:
|
|
options.NamePlaceholders[k] = v.Value()
|
|
options.ValuePlaceholders[k] = &types.AttributeValueMemberS{Value: v.Value()}
|
|
case *object.Int:
|
|
options.ValuePlaceholders[k] = &types.AttributeValueMemberN{Value: fmt.Sprint(v.Value())}
|
|
case *object.Float:
|
|
options.ValuePlaceholders[k] = &types.AttributeValueMemberN{Value: fmt.Sprint(v.Value())}
|
|
case *object.Bool:
|
|
options.ValuePlaceholders[k] = &types.AttributeValueMemberBOOL{Value: v.Value()}
|
|
case *object.NilType:
|
|
options.ValuePlaceholders[k] = &types.AttributeValueMemberNULL{Value: true}
|
|
default:
|
|
return object.Errorf("type error: arg '%v' of type '%v' is not supported", k, val.Type())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
resp, err := um.sessionService.Query(ctx, expr, options)
|
|
|
|
if err != nil {
|
|
return object.NewError(err)
|
|
}
|
|
return &resultSetProxy{resultSet: resp}
|
|
}
|
|
|
|
func (um *sessionModule) resultSet(ctx context.Context, args ...object.Object) object.Object {
|
|
if err := require("session.result_set", 0, args); err != nil {
|
|
return err
|
|
}
|
|
|
|
rs := um.sessionService.ResultSet(ctx)
|
|
if rs == nil {
|
|
return object.Nil
|
|
}
|
|
return &resultSetProxy{resultSet: rs}
|
|
}
|
|
|
|
func (um *sessionModule) selectedItem(ctx context.Context, args ...object.Object) object.Object {
|
|
if err := require("session.result_set", 0, args); err != nil {
|
|
return err
|
|
}
|
|
|
|
rs := um.sessionService.ResultSet(ctx)
|
|
idx := um.sessionService.SelectedItemIndex(ctx)
|
|
if rs == nil || idx < 0 {
|
|
return object.Nil
|
|
}
|
|
|
|
rsProxy := &resultSetProxy{resultSet: rs}
|
|
return newItemProxy(rsProxy, idx)
|
|
}
|
|
|
|
func (um *sessionModule) setResultSet(ctx context.Context, args ...object.Object) object.Object {
|
|
if err := require("session.set_result_set", 1, args); err != nil {
|
|
return err
|
|
}
|
|
|
|
resultSetProxy, isResultSetProxy := args[0].(*resultSetProxy)
|
|
if !isResultSetProxy {
|
|
return object.NewError(errors.Errorf("type error: expected a resultsset (got %v)", args[0]))
|
|
}
|
|
|
|
um.sessionService.SetResultSet(ctx, resultSetProxy.resultSet)
|
|
return nil
|
|
}
|
|
|
|
func (um *sessionModule) currentTable(ctx context.Context, args ...object.Object) object.Object {
|
|
if err := require("session.current_table", 0, args); err != nil {
|
|
return err
|
|
}
|
|
|
|
rs := um.sessionService.ResultSet(ctx)
|
|
if rs == nil {
|
|
return object.Nil
|
|
}
|
|
|
|
return &tableProxy{table: rs.TableInfo}
|
|
}
|
|
|
|
func (um *sessionModule) register() *object.Module {
|
|
return object.NewBuiltinsModule("session", map[string]object.Object{
|
|
"query": object.NewBuiltin("query", um.query),
|
|
"current_table": object.NewBuiltin("current_table", um.currentTable),
|
|
"result_set": object.NewBuiltin("result_set", um.resultSet),
|
|
"selected_item": object.NewBuiltin("selected_item", um.selectedItem),
|
|
"set_result_set": object.NewBuiltin("set_result_set", um.setResultSet),
|
|
})
|
|
}
|