diff --git a/cmd/ast/testdata/case004/output.yaml b/cmd/ast/testdata/case004/output.yaml index f8e58124..a5c7cb5d 100644 --- a/cmd/ast/testdata/case004/output.yaml +++ b/cmd/ast/testdata/case004/output.yaml @@ -1,26 +1,24 @@ parameters: - - assumed: false - datatype: int - id: ID - kind: query - name: id - required: false - - assumed: false - datatype: string - id: quantity - kind: path - name: quantity - required: true + - datatype: int + id: ID + kind: query + name: id + required: false + - datatype: string + id: quantity + kind: path + name: quantity + required: true source: |- - SELECT *, ( - SELECT abc - FROM T2 - WHERE 1=2 - ) as abc FROM T1 - WHERE 1=1 - #if($Has.ID) - AND ID = $ID - #end - #if($Has.quantity) - AND quantity = $quantity - #end + SELECT *, ( + SELECT abc + FROM T2 + WHERE 1=2 + ) as abc FROM T1 + WHERE 1=1 + #if($Has.ID) + AND ID = $ID + #end + #if($Has.quantity) + AND quantity = $quantity + #end diff --git a/cmd/ast/testdata/case005/output.yaml b/cmd/ast/testdata/case005/output.yaml index accf7045..ecc1ff47 100644 --- a/cmd/ast/testdata/case005/output.yaml +++ b/cmd/ast/testdata/case005/output.yaml @@ -1,29 +1,28 @@ parameters: - - assumed: false - datatype: int - id: ID - kind: query - name: id - required: false - - assumed: true - datatype: string - id: quantity - kind: query - name: quantity - required: false - typer: - columnname: quantity + - datatype: int + id: ID + kind: query + name: id + required: false + - assumed: true + datatype: string + id: quantity + kind: query + name: quantity + required: false + typer: + columnname: quantity source: | - SELECT *, ( - SELECT abc - FROM T2 - WHERE 1=2 - ) as abc FROM T1 - WHERE 1=1 - #if($Has.ID) - AND ID = $ID - #end - #if($Has.quantity) - AND quantity = $quantity - AND quantity = $Unsafe.quantity - #end + SELECT *, ( + SELECT abc + FROM T2 + WHERE 1=2 + ) as abc FROM T1 + WHERE 1=1 + #if($Has.ID) + AND ID = $ID + #end + #if($Has.quantity) + AND quantity = $quantity + AND quantity = $Unsafe.quantity + #end diff --git a/cmd/ast/testdata/case006/output.yaml b/cmd/ast/testdata/case006/output.yaml index 8eaaff05..084e6848 100644 --- a/cmd/ast/testdata/case006/output.yaml +++ b/cmd/ast/testdata/case006/output.yaml @@ -1,35 +1,42 @@ parameters: - - assumed: false - datatype: int - id: ID - kind: query - name: id - required: false - - assumed: true - datatype: string - id: quantity - kind: query - name: quantity - required: false - typer: - columnname: quantity + - datatype: int + id: ID + kind: query + name: id + required: false + - assumed: true + cardinality: Many + datatype: string + id: Columns + kind: query + multi: true + name: Columns + required: false + - assumed: true + datatype: string + id: quantity + kind: query + name: quantity + required: false + typer: + columnname: quantity source: | - SELECT *, ( - SELECT abc - FROM T2 - WHERE 1=2 - ) as abc FROM T1 - WHERE 1=1 - #set($valueSet = 123) - #if($Has.ID) - AND ID = $ID - #end - - #foreach($column in $Columns) - $column.Id - #end - - #if($Has.quantity) - AND quantity = $quantity - AND quantity = $Unsafe.quantity - #end + SELECT *, ( + SELECT abc + FROM T2 + WHERE 1=2 + ) as abc FROM T1 + WHERE 1=1 + #set($valueSet = 123) + #if($Has.ID) + AND ID = $ID + #end + + #foreach($column in $Columns) + $column.Id + #end + + #if($Has.quantity) + AND quantity = $quantity + AND quantity = $Unsafe.quantity + #end diff --git a/cmd/ast/testdata/case007/output.yaml b/cmd/ast/testdata/case007/output.yaml index 85baebb6..c4032ac0 100644 --- a/cmd/ast/testdata/case007/output.yaml +++ b/cmd/ast/testdata/case007/output.yaml @@ -1,35 +1,43 @@ parameters: - - assumed: true - datatype: string - id: ID - kind: query - name: ID - required: false - - assumed: true - datatype: string - id: quantity - kind: query - name: quantity - required: false - typer: - columnname: quantity + - assumed: true + datatype: string + id: ID + kind: query + name: ID + required: false + - assumed: true + cardinality: Many + datatype: string + id: Columns + kind: query + multi: true + name: Columns + required: false + - assumed: true + datatype: string + id: quantity + kind: query + name: quantity + required: false + typer: + columnname: quantity source: | - SELECT *, ( - SELECT abc - FROM T2 - WHERE 1=2 - ) as abc FROM T1 - WHERE 1=1 - #set($valueSet = 123) - #if($Has.ID) - AND ID = 10 - #end - - #foreach($column in $Columns) - $column.Id - #end - - #if($Has.quantity) - AND quantity = $quantity - AND quantity = $Unsafe.quantity - #end + SELECT *, ( + SELECT abc + FROM T2 + WHERE 1=2 + ) as abc FROM T1 + WHERE 1=1 + #set($valueSet = 123) + #if($Has.ID) + AND ID = 10 + #end + + #foreach($column in $Columns) + $column.Id + #end + + #if($Has.quantity) + AND quantity = $quantity + AND quantity = $Unsafe.quantity + #end diff --git a/cmd/ast/testdata/case008/output.yaml b/cmd/ast/testdata/case008/output.yaml index 2683aa8b..e7a47f31 100644 --- a/cmd/ast/testdata/case008/output.yaml +++ b/cmd/ast/testdata/case008/output.yaml @@ -1,33 +1,40 @@ parameters: - - assumed: true - datatype: string - id: ID - kind: query - name: ID - required: false - - assumed: false - datatype: time.Time - id: quantity - kind: query - name: quantity - required: false + - assumed: true + datatype: string + id: ID + kind: query + name: ID + required: false + - assumed: true + cardinality: Many + datatype: string + id: Columns + kind: query + multi: true + name: Columns + required: false + - datatype: time.Time + id: quantity + kind: query + name: quantity + required: false source: | - SELECT *, ( - SELECT abc - FROM T2 - WHERE 1=2 - ) as abc FROM T1 - WHERE 1=1 - #set($valueSet = 123) - #if($Has.ID) - AND ID = 10 - #end - - #foreach($column in $Columns) - $column.Id - #end - - #if($Has.quantity) - AND quantity = $quantity /* {"DataType": "time.Time"} */ - AND quantity = $Unsafe.quantity - #end + SELECT *, ( + SELECT abc + FROM T2 + WHERE 1=2 + ) as abc FROM T1 + WHERE 1=1 + #set($valueSet = 123) + #if($Has.ID) + AND ID = 10 + #end + + #foreach($column in $Columns) + $column.Id + #end + + #if($Has.quantity) + AND quantity = $quantity /* {"DataType": "time.Time"} */ + AND quantity = $Unsafe.quantity + #end diff --git a/go.mod b/go.mod index 3f41b7e1..3cccae6d 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/viant/scy v0.2.1-0.20220812183656-68209588b73e github.com/viant/sqlx v0.0.0-20220811174716-1b6dd6d967a2 github.com/viant/toolbox v0.34.6-0.20220630003140-fb2bf82657c1 - github.com/viant/velty v0.1.1-0.20220810215332-b4095f02bc23 + github.com/viant/velty v0.1.1-0.20220815170357-0518dfc48b9d github.com/viant/xunsafe v0.8.1-0.20220609224231-1d3e1fcf7bb6 golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb google.golang.org/api v0.84.0 diff --git a/logger/printer.go b/logger/printer.go new file mode 100644 index 00000000..1ceea784 --- /dev/null +++ b/logger/printer.go @@ -0,0 +1,60 @@ +package logger + +import ( + "fmt" + "github.com/viant/velty/est" + "github.com/viant/velty/est/op" + "github.com/viant/xunsafe" + "reflect" +) + +var stringType = reflect.TypeOf("") + +type Printer struct { +} + +func (p Printer) Discover(aFunc interface{}) (func(operands []*op.Operand, state *est.State) (interface{}, error), reflect.Type, bool) { + switch actual := aFunc.(type) { + case func(_ Printer, args ...interface{}) string: + return func(operands []*op.Operand, state *est.State) (interface{}, error) { + return actual(p, p.asInterfaces(operands, state)), nil + }, stringType, true + + case func(_ Printer, message string, args ...interface{}) string: + return func(operands []*op.Operand, state *est.State) (interface{}, error) { + if len(operands) < 1 { + return nil, fmt.Errorf("expected to get 1 or more arguments but got %v", len(operands)) + } + + format := *(*string)(operands[0].Exec(state)) + args := p.asInterfaces(operands[1:], state) + + return actual(p, format, args...), nil + }, stringType, true + + } + + return nil, nil, false +} + +func (p Printer) asInterfaces(operands []*op.Operand, state *est.State) []interface{} { + args := make([]interface{}, len(operands)) + + for i, operand := range operands { + value := reflect.New(operand.Type).Elem().Interface() + xunsafe.Copy(xunsafe.AsPointer(value), operand.Exec(state), int(operand.Type.Size())) + args[i] = value + } + + return args +} + +func (p Printer) Println(args ...interface{}) string { + fmt.Println(args...) + return "" +} + +func (p Printer) Printf(format string, args ...interface{}) string { + fmt.Printf(format, args...) + return "" +} diff --git a/view/template.go b/view/template.go index 14eb2d3a..c7a6de9e 100644 --- a/view/template.go +++ b/view/template.go @@ -3,6 +3,7 @@ package view import ( "context" "fmt" + "github.com/viant/datly/logger" "github.com/viant/datly/shared" "github.com/viant/datly/view/keywords" "github.com/viant/datly/view/parameter" @@ -212,6 +213,10 @@ func NewEvaluator(paramSchema, presenceSchema reflect.Type, template string) (*E return nil, err } + if err = evaluator.planner.DefineVariable(Logger, reflect.TypeOf(logger.Printer{})); err != nil { + return nil, err + } + evaluator.executor, evaluator.stateProvider, err = evaluator.planner.Compile([]byte(template)) if err != nil { return nil, err diff --git a/view/velty.go b/view/velty.go index 86969eac..51ba75c1 100644 --- a/view/velty.go +++ b/view/velty.go @@ -23,6 +23,7 @@ const ( SafeFloat = "Safe_Float" Criteria = "criteria" + Logger = "logger" ) type Sanitizer struct {