Skip to content

Commit

Permalink
added predicate generator
Browse files Browse the repository at this point in the history
  • Loading branch information
adranwit committed Nov 21, 2024
1 parent 636cc35 commit c55d2d9
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 18 deletions.
2 changes: 1 addition & 1 deletion cmd/command/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (s *Service) generateGet(ctx context.Context, opts *options.Options) (err e

defComp := true
if generate := opts.Generate; generate != nil {
defComp = !generate.NoComponentDef
defComp = !translate.Rule.SkipCompDef
}
opts.Translate = translate
opts.Generate = nil
Expand Down
11 changes: 5 additions & 6 deletions cmd/options/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ import (
type Generate struct {
Repository
Rule
Dest string `short:"d" long:"dest" description:"dql file location" default:"dql"`
Operation string `short:"o" long:"op" description:"operation" choice:"post" choice:"patch" choice:"put" choice:"get"`
Kind string `short:"k" long:"kind" description:"execution kind" choice:"dml" choice:"service"`
Lang string `short:"l" long:"lang" description:"lang" choice:"velty" choice:"go"`
Translate bool `short:"t" long:"translate" description:"translate generated DSQL"`
NoComponentDef bool `short:"Z" long:"noComDef" description:"do not include component definition" `
Dest string `short:"d" long:"dest" description:"dql file location" default:"dql"`
Operation string `short:"o" long:"op" description:"operation" choice:"post" choice:"patch" choice:"put" choice:"get"`
Kind string `short:"k" long:"kind" description:"execution kind" choice:"dml" choice:"service"`
Lang string `short:"l" long:"lang" description:"lang" choice:"velty" choice:"go"`
Translate bool `short:"t" long:"translate" description:"translate generated DSQL"`
}

func (g *Generate) HttpMethod() string {
Expand Down
23 changes: 12 additions & 11 deletions cmd/options/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@ import (
)

type Rule struct {
Project string `short:"p" long:"proj" description:"project location"`
Name string `short:"n" long:"name" description:"rule name"`
ModulePrefix string `short:"u" long:"namespace" description:"rule uri/namespace" default:"dev" `
Source []string `short:"s" long:"src" description:"source"`
Packages []string `short:"g" long:"pkg" description:"entity package"`
Output []string
Index int
ModuleLocation string `short:"m" long:"module" description:"go module package root" default:"pkg"`
module *modfile.Module
Generated bool
SkipCompDef bool `short:"B" long:"sComp" description:"skip component def"`
Project string `short:"p" long:"proj" description:"project location"`
Name string `short:"n" long:"name" description:"rule name"`
ModulePrefix string `short:"u" long:"namespace" description:"rule uri/namespace" default:"dev" `
Source []string `short:"s" long:"src" description:"source"`
Packages []string `short:"g" long:"pkg" description:"entity package"`
Output []string
Index int
ModuleLocation string `short:"m" long:"module" description:"go module package root" default:"pkg"`
module *modfile.Module
Generated bool
SkipCompDef bool `short:"B" long:"sComp" description:"skip component def"`
IncludePredicates bool `short:"K" long:"inclPred" description:"generate predicate code" `
}

// Module returns go module
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,7 @@ github.com/viant/scy v0.12.0 h1:Fo0DHviM1LHjj2XmtgIERmeh+z4X66AUXnUCTswFXT4=
github.com/viant/scy v0.12.0/go.mod h1:Lz1VPlmjVi4ydZ5ikP/d5uQS/xYs22HG23++PgLRlKQ=
github.com/viant/sqlparser v0.7.5 h1:LLJ/Y2uaqDKm94U2mr6ewnBuNl3L3+nvkDFRolM6w5M=
github.com/viant/sqlparser v0.7.5/go.mod h1:2QRGiGZYk2/pjhORGG1zLVQ9JO+bXFhqIVi31mkCRPg=
github.com/viant/sqlx v0.16.0/go.mod h1:dizufL+nTNqDCpivUnE2HqtddTp2TdA6WFghGfZo11c=
github.com/viant/structology v0.6.1 h1:Forza+RF/1tmlQFk9ABNhu+IQ8vMAqbYM6FOsYtGh9E=
github.com/viant/structology v0.6.1/go.mod h1:63XfkzUyNw7wdi99HJIsH2Rg3d5AOumqbWLUYytOkxU=
github.com/viant/structql v0.5.2 h1:0dAratszxC6AD/TNaV8BnLQQprNO5GJHaKjmszrIoeY=
Expand Down
101 changes: 101 additions & 0 deletions internal/translator/predicate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package translator

import (
"fmt"
"github.com/viant/datly/internal/inference"
"github.com/viant/datly/view/state"
"github.com/viant/tagly/format/text"
"reflect"
"strings"
)

// generateInputPredicate to create the flattened struct
func (s *Service) generateInputPredicate(t reflect.Type, alias string, resource *Resource) {
rootPkgPath := t.PkgPath()
addPredicateParameters(t, "", rootPkgPath, alias, resource)

}

// Helper function to recursively flatten struct fields
func addPredicateParameters(t reflect.Type, prefix string, rootPkgPath string, alias string, resource *Resource) {
switch t.Kind() {
case reflect.Ptr:
addPredicateParameters(t.Elem(), prefix, rootPkgPath, alias, resource)
case reflect.Struct:
if t.PkgPath() == rootPkgPath || t.PkgPath() == "" {
// Inline the struct
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
fieldName := field.Name

sqlxTag := field.Tag.Get("json")
if sqlxTag == "-" {
continue
}
jsonTag := field.Tag.Get("json")
if jsonTag == "-" {
continue
}
jsonFieldName := strings.Split(jsonTag, ",")[0]
if jsonFieldName != "" {
fieldName = jsonFieldName
}
newPrefix := prefix
if newPrefix != "" {
newPrefix += "."
}
newPrefix += fieldName
addPredicateParameters(field.Type, newPrefix, rootPkgPath, alias, resource)
}
} else {
// For types outside the root package, treat as leaf
addPredicateParameter(t, prefix, resource)
}
case reflect.Slice, reflect.Array:
// For slices or arrays, treat as leaf
addPredicateParameters(t.Elem(), prefix, rootPkgPath, alias, resource)
default:
// For basic types, add field
addPredicateParameter(t, prefix, resource)
}
}

// Helper function to add a field to the fields slice
func addPredicateParameter(t reflect.Type, prefix string, resource *Resource) {
// Determine field name

fieldName := strings.ToLower(strings.ReplaceAll(prefix, ".", "_"))
fieldName = text.CaseFormatLowerUnderscore.Format(fieldName, text.CaseFormatUpperCamel)

// Determine field type and predicate
var fieldType reflect.Type
var predicate string

// Check if the last part of the prefix ends with "id" (case-insensitive)
parts := strings.Split(prefix, ".")
lastPart := parts[len(parts)-1]
if strings.HasSuffix(strings.ToLower(lastPart), "id") {
// Use "in" predicate and slice type
fieldType = reflect.SliceOf(reflect.TypeOf(""))
predicate = fmt.Sprintf("in,group=0,a,%s", prefix)
} else if t.Kind() == reflect.String || (t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.String) {
// Use "like" predicate and string type
fieldType = reflect.TypeOf("")
predicate = fmt.Sprintf("like,group=0,a,%s", prefix)
} else {
// For other types, use their default type
fieldType = t
predicate = fmt.Sprintf("eq,group=0,a,%s", prefix)
}

if fieldName == "" {
fmt.Println()
return
}
parameter := inference.Parameter{}
parameter.In = state.NewQueryLocation(prefix)
parameter.Name = fieldName
parameter.Schema = state.NewSchema(fieldType)
parameter.Tag = fmt.Sprintf(`predicate:"%s"`, predicate)
resource.State.Append(&parameter)
}
7 changes: 7 additions & 0 deletions internal/translator/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,12 @@ func (s *Service) translateReaderDSQL(ctx context.Context, resource *Resource, d
}
s.detectComponentViewType(componentColumns, resource)

if resource.rule.IncludePredicates {
if viewSchema := root.Schema; viewSchema != nil && viewSchema.Type() != nil {
s.generateInputPredicate(viewSchema.Type(), rootViewlet.Table.Namespace, resource)
}
}

if err = s.updateOutputParameters(resource, rootViewlet); err != nil {
return err
}
Expand All @@ -236,6 +242,7 @@ func (s *Service) translateReaderDSQL(ctx context.Context, resource *Resource, d
}); err != nil {
return err
}

if err = s.persistRouterRule(ctx, resource, service.TypeReader); err != nil {
return err
}
Expand Down

0 comments on commit c55d2d9

Please sign in to comment.