Skip to content

Commit 57451cf

Browse files
committed
Merge branch 'feat/projects' into dev
2 parents 76eb3fa + e1de598 commit 57451cf

File tree

12 files changed

+28406
-15435
lines changed

12 files changed

+28406
-15435
lines changed

db/gql.go

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ var gqlQueries map[string]string = map[string]string{
5151
}"
5252
}`,
5353

54-
// MUTATIONS
54+
// MUTATIONS - @todo merge with bridger query ?
5555
"add": `{
5656
"query": "mutation {{.QueryName}}($input:[{{.InputType}}!]!) {
5757
{{.QueryName}}(input: $input) {
@@ -82,7 +82,7 @@ var gqlQueries map[string]string = map[string]string{
8282
"input": {{.InputPayload}}
8383
}
8484
}`,
85-
// Extra
85+
// Extra - Bridge
8686
"addExtra": `{
8787
"query": "mutation {{.QueryName}}($input:[{{.InputType}}!]!){
8888
{{.QueryName}}{{.QueryInput}} {
@@ -93,6 +93,16 @@ var gqlQueries map[string]string = map[string]string{
9393
"input": {{.InputPayload}}
9494
}
9595
}`,
96+
"mutationExtra": `{
97+
"query": "mutation {{.QueryName}}($input:{{.InputType}}!){
98+
{{.QueryName}}{{.QueryInput}} {
99+
{{.QueryGraph}}
100+
}
101+
}",
102+
"variables": {
103+
"input": {{.InputPayload}}
104+
}
105+
}`,
96106
}
97107

98108
//
@@ -313,6 +323,10 @@ func (dg Dgraph) UpdateValue(uctx model.UserCtx, vertex string, id, k, v string)
313323
return err
314324
}
315325

326+
//
327+
// Bridge queries
328+
//
329+
316330
// Add codec, to be used in the resolver functions
317331
func (dg Dgraph) AddExtra(uctx model.UserCtx, vertex string, input interface{}, upsert *bool, qg string, data interface{}) error {
318332
Vertex := strings.Title(vertex)
@@ -355,6 +369,78 @@ func (dg Dgraph) AddExtra(uctx model.UserCtx, vertex string, input interface{},
355369
return err
356370
}
357371

372+
// Update codec, to be used in the resolver functions
373+
func (dg Dgraph) UpdateExtra(uctx model.UserCtx, vertex string, input interface{}, qg string, data interface{}) error {
374+
Vertex := strings.Title(vertex)
375+
queryName := "update" + Vertex
376+
inputType := "Update" + Vertex + "Input"
377+
//queryGraph := vertex + " {" + qgraph + "}"
378+
379+
// Build the string request
380+
var queryInput string = "(input: $input)"
381+
var inputs string
382+
slice, ok := InterfaceSlice(input)
383+
if ok {
384+
var ipts []string
385+
for _, x := range slice {
386+
s, _ := MarshalWithoutNil(x)
387+
ipts = append(ipts, string(s))
388+
}
389+
inputs = "[" + strings.Join(ipts, ",") + "]"
390+
} else {
391+
x, _ := MarshalWithoutNil(input)
392+
inputs = string(x)
393+
}
394+
395+
reqInput := map[string]string{
396+
"QueryName": queryName, // Query name (e.g addUser)
397+
"InputType": inputType, // input type name (e.g AddUserInput)
398+
"QueryInput": QuoteString(queryInput), // inputs data
399+
"QueryGraph": CleanString(qg, true), // output data
400+
"InputPayload": string(inputs), // inputs data
401+
}
402+
403+
// Send request
404+
err := dg.QueryGql(uctx, "mutationExtra", reqInput, data)
405+
return err
406+
}
407+
408+
// Delete codec, to be used in the resolver functions
409+
func (dg Dgraph) DeleteExtra(uctx model.UserCtx, vertex string, input interface{}, qg string, data interface{}) error {
410+
Vertex := strings.Title(vertex)
411+
queryName := "delete" + Vertex
412+
inputType := Vertex + "Filter"
413+
//queryGraph := vertex + " {" + qgraph + "}"
414+
415+
// Build the string request
416+
var queryInput string = "(filter: $input)"
417+
var inputs string
418+
slice, ok := InterfaceSlice(input)
419+
if ok {
420+
var ipts []string
421+
for _, x := range slice {
422+
s, _ := MarshalWithoutNil(x)
423+
ipts = append(ipts, string(s))
424+
}
425+
inputs = "[" + strings.Join(ipts, ",") + "]"
426+
} else {
427+
x, _ := MarshalWithoutNil(input)
428+
inputs = string(x)
429+
}
430+
431+
reqInput := map[string]string{
432+
"QueryName": queryName, // Query name (e.g addUser)
433+
"InputType": inputType, // input type name (e.g AddUserInput)
434+
"QueryInput": QuoteString(queryInput), // inputs data
435+
"QueryGraph": CleanString(qg, true), // output data
436+
"InputPayload": string(inputs), // inputs data
437+
}
438+
439+
// Send request
440+
err := dg.QueryGql(uctx, "mutationExtra", reqInput, data)
441+
return err
442+
}
443+
358444
//
359445
// Private User methods
360446
//

graph/FieldTransform.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"fmt"
2626
"strings"
2727
"github.com/99designs/gqlgen/graphql"
28+
"fractale/fractal6.go/graph/model"
2829
)
2930

3031
var FieldTransformFunc map[string]func(context.Context, graphql.Resolver) (interface{}, error)
@@ -37,6 +38,14 @@ func init() {
3738

3839
}
3940

41+
// need https://github.com/golang/go/issues/51977
42+
//type StringEqFilter interface {
43+
// model.StringExactFilter |
44+
// model.StringHashFilter |
45+
// model.StringHashFilterStringRegExpFilter |
46+
// model.StringHashFilterStringTermFilter
47+
// //SetEq(s string)
48+
//}
4049

4150
func lower(ctx context.Context, next graphql.Resolver) (interface{}, error) {
4251
data, err := next(ctx)
@@ -47,6 +56,34 @@ func lower(ctx context.Context, next graphql.Resolver) (interface{}, error) {
4756
case string:
4857
v := strings.ToLower(d)
4958
return v, err
59+
case *model.StringExactFilter:
60+
v := *d
61+
if v.Eq != nil {
62+
s := strings.ToLower(*v.Eq)
63+
v.Eq = &s
64+
}
65+
return &v, err
66+
case *model.StringHashFilter:
67+
v := *d
68+
if v.Eq != nil {
69+
s := strings.ToLower(*v.Eq)
70+
v.Eq = &s
71+
}
72+
return &v, err
73+
case *model.StringHashFilterStringRegExpFilter:
74+
v := *d
75+
if v.Eq != nil {
76+
s := strings.ToLower(*v.Eq)
77+
v.Eq = &s
78+
}
79+
return &v, err
80+
case *model.StringHashFilterStringTermFilter:
81+
v := *d
82+
if v.Eq != nil {
83+
s := strings.ToLower(*v.Eq)
84+
v.Eq = &s
85+
}
86+
return &v, err
5087
}
5188
field := *graphql.GetPathContext(ctx).Field
5289
return nil, fmt.Errorf("Type unknwown for field %s", field)

graph/dgraph_resolver.go

Lines changed: 87 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -40,26 +40,91 @@ func init() {
4040
cache = sessions.GetCache()
4141
}
4242

43+
/* Raw bridges pass the raw query from the request context to Dgraph.
44+
* @Warning: It looses transformation that eventually happen in the resolvers/directives.
45+
*/
4346

44-
func (r *queryResolver) Gqlgen2DgraphQueryResolver(ctx context.Context, data interface{}) error {
45-
return DgraphRawQueryResolver(ctx, data, r.db)
47+
func (r *queryResolver) DgraphBridgeRaw(ctx context.Context, data interface{}) error {
48+
err := DgraphQueryResolverRaw(ctx, r.db, data)
49+
return postGqlProcess(ctx, r.db, data, err)
4650
}
4751

48-
func (r *mutationResolver) Gqlgen2DgraphQueryResolver(ctx context.Context, data interface{}) error {
49-
return DgraphRawQueryResolver(ctx, data, r.db)
52+
func (r *mutationResolver) DgraphBridgeRaw(ctx context.Context, data interface{}) error {
53+
err := DgraphQueryResolverRaw(ctx, r.db, data)
54+
return postGqlProcess(ctx, r.db, data, err)
5055
}
5156

52-
//func (r *mutationResolver) Gqlgen2DgraphMutationResolver(ctx context.Context, ipts interface{}, data interface{}) error {
53-
// return DgraphQueryResolver(ctx, ipts, data, r.db)
54-
//}
57+
/* Those bridges rebuild the query from the request context preloads, and uses the input
58+
* parameters from the gqlgen resolvers whuch reflext the modifications in the resolvers/directives.
59+
* @Warning: It looses eventual directive in the query graph (@cascade, @skip etc)
60+
*/
61+
62+
func (r *queryResolver) DgraphGetBridge(ctx context.Context, maps map[string]interface{}, data interface{}) error {
63+
panic(fmt.Errorf("not implemented"))
64+
}
65+
66+
func (r *queryResolver) DgraphQueryBridge(ctx context.Context, maps map[string]interface{}, data interface{}) error {
67+
panic(fmt.Errorf("not implemented"))
68+
}
69+
70+
func (r *mutationResolver) DgraphAddBridge(ctx context.Context, input interface{}, upsert *bool, data interface{}) error {
71+
err := DgraphAddResolver(ctx, r.db, input, upsert, data)
72+
return postGqlProcess(ctx, r.db, data, err)
73+
}
74+
75+
func (r *mutationResolver) DgraphUpdateBridge(ctx context.Context, input interface{}, data interface{}) error {
76+
err := DgraphUpdateResolver(ctx, r.db, input, data)
77+
return postGqlProcess(ctx, r.db, data, err)
78+
}
79+
80+
func (r *mutationResolver) DgraphDeleteBridge(ctx context.Context, filter interface{}, data interface{}) error {
81+
err := DgraphDeleteResolver(ctx, r.db, filter, data)
82+
return postGqlProcess(ctx, r.db, data, err)
83+
}
5584

5685
/*
5786
*
5887
* Dgraph-Gqlgen bridge logic
5988
*
6089
*/
6190

62-
func DgraphRawQueryResolver(ctx context.Context, data interface{}, db *db.Dgraph) error {
91+
func DgraphAddResolver(ctx context.Context, db *db.Dgraph, input interface{}, upsert *bool, data interface{}) error {
92+
_, uctx, err := auth.GetUserContext(ctx)
93+
if err != nil { return tools.LogErr("Access denied", err) }
94+
95+
_, typeName, _, err := queryTypeFromGraphqlContext(ctx)
96+
if err != nil { return tools.LogErr("DgraphQueryResolver", err) }
97+
98+
err = db.AddExtra(*uctx, typeName, input, upsert, GetQueryGraph(ctx), data)
99+
return err
100+
}
101+
102+
func DgraphUpdateResolver(ctx context.Context, db *db.Dgraph, input interface{}, data interface{}) error {
103+
_, uctx, err := auth.GetUserContext(ctx)
104+
if err != nil { return tools.LogErr("Access denied", err) }
105+
106+
_, typeName, _, err := queryTypeFromGraphqlContext(ctx)
107+
if err != nil { return tools.LogErr("DgraphQueryResolver", err) }
108+
109+
err = db.UpdateExtra(*uctx, typeName, input, GetQueryGraph(ctx), data)
110+
return err
111+
}
112+
113+
func DgraphDeleteResolver(ctx context.Context, db *db.Dgraph, input interface{}, data interface{}) error {
114+
_, uctx, err := auth.GetUserContext(ctx)
115+
if err != nil { return tools.LogErr("Access denied", err) }
116+
117+
_, typeName, _, err := queryTypeFromGraphqlContext(ctx)
118+
if err != nil { return tools.LogErr("DgraphQueryResolver", err) }
119+
120+
err = db.DeleteExtra(*uctx, typeName, input, GetQueryGraph(ctx), data)
121+
return err
122+
}
123+
124+
// @deprecated: Follow the Gql request to Dgraph.
125+
// This use raw query from the request context and thus won't propage change
126+
// of the input that may happend in the resolvers.
127+
func DgraphQueryResolverRaw(ctx context.Context, db *db.Dgraph, data interface{}) error {
63128
// How to get the query args ? https://github.com/99designs/gqlgen/issues/1144
64129
// for k, a := range rc.Args {
65130

@@ -86,7 +151,7 @@ func DgraphRawQueryResolver(ctx context.Context, data interface{}, db *db.Dgraph
86151
rawQuery = reg.ReplaceAllString(rawQuery, "history:[]")
87152

88153
// If Graphql variables are given...
89-
t := strings.ToLower(typeName)
154+
t := strings.ToLower(typeName) // @DEBUG: only the first letter must lowered ?!
90155
if variables[t] != nil && variables[t].(map[string]interface{})["set"] != nil {
91156
s := variables[t].(map[string]interface{})["set"].(map[string]interface{})
92157
s["history"] = nil
@@ -105,10 +170,14 @@ func DgraphRawQueryResolver(ctx context.Context, data interface{}, db *db.Dgraph
105170
// Send request
106171
uctx := auth.GetUserContextOrEmpty(ctx)
107172
err = db.QueryGql(uctx, "rawQuery", reqInput, data)
108-
if data != nil && err != nil {
173+
return err
174+
}
175+
176+
func postGqlProcess(ctx context.Context, db *db.Dgraph, data interface{}, errors error) error {
177+
if data != nil && errors != nil {
109178
// Gqlgen ignore the data if there is an error returned
110179
// see https://github.com/99designs/gqlgen/issues/1191
111-
//graphql.AddErrorf(ctx, err.Error())
180+
//graphql.AddErrorf(ctx, errors.Error())
112181

113182
// Nodes query can return null field if Node are hidden
114183
// but children are not. The source ends up to be a tension where
@@ -118,14 +187,16 @@ func DgraphRawQueryResolver(ctx context.Context, data interface{}, db *db.Dgraph
118187
if (string(d) == "null") {
119188
// If there is really no data, show the graphql error
120189
// otherwise, fail silently.
121-
return err
190+
return errors
122191
}
123-
fmt.Println("Dgraph Error Ignored: ", err.Error())
192+
fmt.Println("Dgraph Error Ignored: ", errors.Error())
124193
return nil
125-
} else if err != nil || data == nil {
126-
return err
194+
} else if errors != nil || data == nil {
195+
return errors
127196
}
128197

198+
uctx := auth.GetUserContextOrEmpty(ctx)
199+
if uctx.Username == "" { return errors }
129200
// Post processing (@meta_patch) / Post hook operation.
130201
// If the query go trough the validation stack, execute.
131202
//if f, _ := cache.Do("GETDEL", uctx.Username + "meta_patch_f"); f != nil {
@@ -144,51 +215,5 @@ func DgraphRawQueryResolver(ctx context.Context, data interface{}, db *db.Dgraph
144215
//fmt.Println("Redis error: ", err)
145216
}
146217

147-
return err
218+
return errors
148219
}
149-
150-
//// Mutation type Enum
151-
//type mutationType string
152-
//const (
153-
// AddMut mutationType = "add"
154-
// UpdateMut mutationType = "update"
155-
// DelMut mutationType = "delete"
156-
//)
157-
//type MutationContext struct {
158-
// type_ mutationType
159-
// argName string
160-
//}
161-
162-
163-
//// @Debug: GetPreloads loose subfilter in payload(in QueryGraph)
164-
//func DgraphQueryResolver(ctx context.Context, ipts interface{}, data interface{}, db *db.Dgraph) error {
165-
// mutCtx := ctx.Value("mutation_context").(MutationContext)
166-
//
167-
// /* Rebuild the Graphql inputs request from this context */
168-
// rc := graphql.GetResolverContext(ctx)
169-
// queryName := rc.Field.Name
170-
//
171-
// // Format inputs
172-
// inputs, _ := json.Marshal(ipts)
173-
// // If inputs needs to get modified, see tools.StructToMap() usage
174-
// // in order to to get the struct in the schema.resolver caller.
175-
//
176-
// // Format collected fields
177-
// inputType := strings.Split(fmt.Sprintf("%T", rc.Args[mutCtx.argName]), ".")[1]
178-
// queryGraph := GetQueryGraph(ctx)
179-
//
180-
// // Build the graphql raw request
181-
// reqInput := map[string]string{
182-
// "QueryName": queryName, // function name (e.g addUser)
183-
// "InputType": inputType, // input type name (e.g AddUserInput)
184-
// "QueryGraph": queryGraph, // output data
185-
// "InputPayload": string(inputs), // inputs data
186-
// }
187-
//
188-
// op := string(mutCtx.type_)
189-
//
190-
// // Send request
191-
// uctx := auth.GetUserContextOrEmpty(ctx)
192-
// err = db.QueryGql(uctx, op, reqInput, data)
193-
// return err
194-
//}

0 commit comments

Comments
 (0)