Skip to content

Commit

Permalink
last checkpoint before refactor query grab
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewpeterkort committed Dec 18, 2024
1 parent 3108fd4 commit e87bca4
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 52 deletions.
14 changes: 8 additions & 6 deletions gql-gen/graph/collectFields.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,17 @@ func refinePaths(fields []string) []string {
}
refinedField := strings.Join(segments, ".")
refined = append(refined, refinedField)

}

return refined
}

func SortFieldPaths(fields []string, rootType string) []string {
refined := refinePaths(fields)
sort.Slice(refined, func(i, j int) bool {
countTypeI, nestingLevelI := countTypeOccurrencesAndLevels(refined[i])
countTypeJ, nestingLevelJ := countTypeOccurrencesAndLevels(refined[j])
//refined := refinePaths(fields)
sort.Slice(fields, func(i, j int) bool {
countTypeI, nestingLevelI := countTypeOccurrencesAndLevels(fields[i])
countTypeJ, nestingLevelJ := countTypeOccurrencesAndLevels(fields[j])

// Prioritize fewer "Type" segments
if countTypeI != countTypeJ {
Expand All @@ -45,9 +47,9 @@ func SortFieldPaths(fields []string, rootType string) []string {
if nestingLevelI != nestingLevelJ {
return nestingLevelI < nestingLevelJ
}
return refined[i] < refined[j]
return fields[i] < fields[j]
})
return refined
return fields
}

// Helper function to count "Type" segments and nesting levels
Expand Down
47 changes: 41 additions & 6 deletions gql-gen/graph/gripFetch.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package graph

import (
"context"
"fmt"
"strings"

"github.com/bmeg/grip/gripql"
)
Expand All @@ -10,13 +12,46 @@ type Resolver struct {
GripDb gripql.Client
}

func gripQuery(fields []string, sourceType string) *gripql.Query {
query := gripql.V().HasLabel(sourceType).As("_" + sourceType)
func (r *queryResolver) gripQuery(fields []string, sourceType string) []any {
sourceTypeLen := len(sourceType)
fmt.Println("SOURCE TYPE: ", sourceType[:sourceTypeLen-4])
query := gripql.V().HasLabel(sourceType[:sourceTypeLen-4]).As(sourceType)
for i, field := range fields {
fields[i] = sourceType + "." + field
}
typeGraph, traversal := constructTypeTraversal(fields)
fmt.Println("TYPE GRAPH: ", typeGraph)
fmt.Println("Traversal Path", traversal)
return query
traversal, typeGraph := constructTypeTraversal(fields)

// Construct query from template traversal string
for _, value := range traversal {
if strings.HasPrefix(value, "OUTNULL_") {
splitStr := strings.Split(value, "_")
//fmt.Println("SPLIT STR: ", splitStr)
query = query.OutNull(splitStr[1] + "_" + splitStr[2][:len(splitStr[2])-4]).As(splitStr[2])
} else if strings.HasPrefix(value, "SELECT_") {
//fmt.Println("VALUE SELECT : ", value[7:])
query = query.Select(value[7:])
}
}

render := map[string]any{}
for typeKey, typeVals := range typeGraph {
for _, val := range typeVals {
render[typeKey+"_"+val] = "$" + typeKey + "." + val
}
}
query = query.Render(render)
fmt.Println("RENDER: ", render)

fmt.Println("STATEMENTS: ", query.Statements)
result, err := r.GripDb.Traversal(context.Background(), &gripql.GraphQuery{Graph: "CALIPER", Query: query.Statements})
if err != nil {
return nil
}

out := []any{}
for r := range result {
out = append(out, r.GetRender().GetStructValue().AsMap())
}

return out
}
5 changes: 3 additions & 2 deletions gql-gen/graph/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ package graph

import (
"context"
"fmt"

"github.com/bmeg/grip-graphql/gql-gen/generated"

"github.com/bmeg/grip-graphql/gql-gen/model"
//"github.com/vektah/gqlparser/v2/ast"
)

// Organization is the resolver for the organization field.
Expand Down Expand Up @@ -65,7 +65,8 @@ func (r *queryResolver) Specimen(ctx context.Context, offset *int, first *int, f
func (r *queryResolver) Observation(ctx context.Context, offset *int, first *int, filter *string, sort *string, accessibility *model.Accessibility, format *model.Format) ([]*model.ObservationType, error) {
sourceType := "ObservationType"
fields := GetQueryFields(ctx, sourceType)
_ = gripQuery(fields, sourceType)
res := r.gripQuery(fields, sourceType)
fmt.Println("RES: ", res)

/*for _, field := range fields {
fmt.Println("PATH: ", field)
Expand Down
35 changes: 21 additions & 14 deletions gql-gen/graph/traversal.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import (
)

type Node struct {
value string
children map[string]*Node
fields []string
visited bool
value string
children map[string]*Node
fields []string
referenceName string
visited bool
}

func createNodeGraph(paths []string) *Node {
fmt.Println("ENTRY PATHS: ", paths)
/* Construct a Node graph from a list of '.' delimited traversal paths */
graph := &Node{
children: make(map[string]*Node),
Expand All @@ -21,33 +23,38 @@ func createNodeGraph(paths []string) *Node {
for _, path := range paths {
parts := strings.Split(path, ".")
current := graph

var referenceName string
var lstTypeIndex int
for i, part := range parts {
if strings.HasSuffix(part, "Type") && !strings.HasSuffix(part, "resourceType") {
lstTypeIndex = i
if _, ok := current.children[part]; !ok {
current.children[part] = &Node{
value: part,
children: make(map[string]*Node),
value: part,
children: make(map[string]*Node),
referenceName: referenceName,
}
}
current = current.children[part]
} else {
current.fields = append(current.fields, strings.Join(parts[i:], "."))
break
if i+1 == len(parts) {
current.fields = append(current.fields, strings.Join(parts[lstTypeIndex+1:], "."))
}
referenceName = parts[i]
}
}
}
return graph
}

func constructTypeTraversal(paths []string) (string, map[string][]string) {
func constructTypeTraversal(paths []string) ([]string, map[string][]string) {
//Build traversal using a modifed Depth First Search algorithm
typeFields := make(map[string][]string)
returnPath, traversalPath := []string{}, []string{}
stack := []*Node{}

graph := createNodeGraph(paths)

printNode(graph, 0)
for node := range graph.children {
if strings.HasSuffix(node, "Type") {
stack = append(stack, graph.children[node])
Expand All @@ -61,7 +68,6 @@ func constructTypeTraversal(paths []string) (string, map[string][]string) {
continue
}
current.visited = true

// Append fields on each node to typeFields
if len(current.fields) > 0 {
typeFields[current.value] = append(typeFields[current.value], current.fields...)
Expand All @@ -76,15 +82,16 @@ func constructTypeTraversal(paths []string) (string, map[string][]string) {

traversalPath = append(traversalPath, current.value)
if len(traversalPath) > 1 {
returnPath = append(returnPath, "OUTNULL_"+current.value)
returnPath = append(returnPath, "OUTNULL_"+current.referenceName+"_"+current.value)
}

for _, child := range current.children {
stack = append(stack, child)
}
}

return strings.Join(returnPath, "."), typeFields
fmt.Println("RETURN PATH: ", returnPath, typeFields)
return returnPath, typeFields
}

func findParentNode(graph *Node, node *Node) string {
Expand Down
60 changes: 36 additions & 24 deletions gql-gen/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,46 @@ import (
)

type Handler struct {
router *gin.Engine
config map[string]string
router *gin.Engine
config map[string]string
handler *handler.Server
client gripql.Client
}

func (gh *Handler) graphqlHandler(client gripql.Client) gin.HandlerFunc {
// NewExecutableSchema and Config are in the generated.go file
// Resolver is in the resolver.go file
srv := handler.New(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{
//GripClient: client,
GripDb: client,
}}))
gh.handler = srv

srv.AddTransport(transport.Options{})
srv.AddTransport(transport.GET{})
srv.AddTransport(transport.POST{})
srv.SetQueryCache(lru.New[*ast.QueryDocument](1000))
gh.handler.AddTransport(transport.Options{})
gh.handler.AddTransport(transport.GET{})
gh.handler.AddTransport(transport.POST{})
gh.handler.SetQueryCache(lru.New[*ast.QueryDocument](1000))

srv.Use(extension.Introspection{})
srv.Use(extension.AutomaticPersistedQuery{
gh.handler.Use(extension.Introspection{})
gh.handler.Use(extension.AutomaticPersistedQuery{
Cache: lru.New[string](100),
})

return func(c *gin.Context) {
srv.ServeHTTP(c.Writer, c.Request)
gh.handler.ServeHTTP(c.Writer, c.Request)
//c.Next()
}
}

func (gh *Handler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
log.Infoln("HELLO INSIDE SERVE HTTP ", request)
gh.router.ServeHTTP(writer, request)
}

func playgroundHandler() gin.HandlerFunc {
h := playground.Handler("GraphQL Playground", "/graphql/query")
return func(c *gin.Context) {
h.ServeHTTP(c.Writer, c.Request)
}
}

func NewHTTPHandler(client gripql.Client, config map[string]string) (http.Handler, error) {
// Setting up Gin
r := gin.New()
Expand All @@ -59,26 +69,28 @@ func NewHTTPHandler(client gripql.Client, config map[string]string) (http.Handle
}
log.ConfigureLogger(logConfig)
r.Use(gin.Logger())
r.NoRoute(func(c *gin.Context) {
log.WithFields(log.Fields{
"graph": nil,
"status": "404",
}).Info(c.Request.URL.Path + " Not Found")
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"status": "404",
"message": c.Request.URL.Path + " Not Found",
"data": nil,
})
/*r.NoRoute(func(c *gin.Context) {
log.WithFields(log.Fields{
"graph": nil,
"status": "404",
}).Info(c.Request.URL.Path + " Not Found")
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"status": "404",
"message": c.Request.URL.Path + " Not Found",
"data": nil,
})
})*/
r.Use(gin.Recovery())

r.RemoveExtraSlash = true

h := &Handler{
router: r,
config: config,
client: client,
}
r.POST("/query", h.graphqlHandler(client))
r.GET("/", gin.WrapH(playground.Handler("GraphQL", "/query"))) //r.GET("/", playgroundHandler())
r.Run()
r.GET("/", playgroundHandler())
return h, nil

}

0 comments on commit e87bca4

Please sign in to comment.