github.com/mithrandie/csvq@v1.18.1/lib/action/calc.go (about) 1 package action 2 3 import ( 4 "context" 5 "errors" 6 "strings" 7 8 "github.com/mithrandie/csvq/lib/option" 9 "github.com/mithrandie/csvq/lib/parser" 10 "github.com/mithrandie/csvq/lib/query" 11 ) 12 13 func Calc(ctx context.Context, proc *query.Processor, expr string) error { 14 _ = proc.Tx.SetFlag(option.NoHeaderFlag, true) 15 q := "SELECT " + expr + " FROM STDIN" 16 17 program, _, err := parser.Parse(q, "", false, proc.Tx.Flags.AnsiQuotes) 18 if err != nil { 19 e := err.(*parser.SyntaxError) 20 e.SourceFile = "" 21 e.Line = 0 22 e.Char = 0 23 e.Message = "syntax error" 24 return query.NewSyntaxError(e) 25 } 26 selectEntity, _ := program[0].(parser.SelectQuery).SelectEntity.(parser.SelectEntity) 27 28 scope := query.NewReferenceScope(proc.Tx) 29 queryScope := scope.CreateNode() 30 31 view, err := query.LoadView(ctx, queryScope, selectEntity.FromClause.(parser.FromClause).Tables, false, false) 32 if err != nil { 33 if appErr, ok := err.(query.Error); ok { 34 err = errors.New(appErr.Message()) 35 } 36 return err 37 } 38 39 clause := selectEntity.SelectClause.(parser.SelectClause) 40 41 recordScope := scope.CreateScopeForRecordEvaluation(view, 0) 42 values := make([]string, len(clause.Fields)) 43 for i, v := range clause.Fields { 44 field := v.(parser.Field) 45 p, err := query.Evaluate(ctx, recordScope, field.Object) 46 if err != nil { 47 if appErr, ok := err.(query.Error); ok { 48 err = errors.New(appErr.Message()) 49 } 50 return err 51 } 52 values[i], _, _ = query.ConvertFieldContents(p, true, proc.Tx.Flags.ExportOptions.ScientificNotation) 53 } 54 55 return proc.Tx.Session.WriteToStdout(strings.Join(values, string(proc.Tx.Flags.ExportOptions.Delimiter))) 56 }