diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..13566b81 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/graphql-go.iml b/.idea/graphql-go.iml new file mode 100644 index 00000000..5e764c4f --- /dev/null +++ b/.idea/graphql-go.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..6bc9c1ea --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/internal/exec/exec.go b/internal/exec/exec.go index 07e4c7ed..ce054884 100644 --- a/internal/exec/exec.go +++ b/internal/exec/exec.go @@ -7,6 +7,7 @@ import ( errlib "errors" "fmt" "reflect" + "strconv" "sync" "github.com/tokopedia/graphql-go/errors" @@ -41,21 +42,55 @@ func makePanicError(value interface{}) *errors.QueryError { return errors.Errorf("graphql: panic occurred: %v", value) } +var myMap = make(map[string]string) +var mutex = &sync.RWMutex{} + +var objMap = map[string]int{ + "String": 0, + "Int": 0, +} +var cost = 0 +var firstTime = true + func (r *Request) Execute(ctx context.Context, s *resolvable.Schema, op *query.Operation) ([]byte, []*errors.QueryError) { var out bytes.Buffer + myMap = make(map[string]string) + cost = 0 func() { defer r.handlePanic(ctx) sels := selected.ApplyOperation(&r.Request, s, op) r.execSelections(ctx, sels, nil, s, s.Resolver, &out, op.Type == query.Mutation) }() - if err := ctx.Err(); err != nil { return nil, []*errors.QueryError{errors.Errorf("%s", err)} } - + if !firstTime { + out.WriteByte(',') + out.WriteByte('"') + out.WriteString("QueryCost") + out.WriteByte('"') + out.WriteByte(':') + out.WriteByte([]byte(calculateTheCost())[0]) + } else { + firstTime = false + } return out.Bytes(), r.Errs } +func calculateTheCost() string { + mutex.Lock() + cost = 0 + for _, v := range myMap { + if _, ok := objMap[v]; !ok { + cost += 1 + } else { + cost += objMap[v] + } + } + mutex.Unlock() + return strconv.Itoa(cost) +} + type fieldToExec struct { field *selected.SchemaField sels []selected.Selection @@ -202,6 +237,9 @@ func execFieldSelection(ctx context.Context, r *Request, s *resolvable.Schema, f in = append(in, f.field.PackedArgs) } callOut := f.resolver.Method(f.field.MethodIndex).Call(in) + mutex.Lock() + myMap[f.field.Alias] = f.field.Type.String() + mutex.Unlock() result = callOut[0] if f.field.HasError && !callOut[1].IsNil() { graphQLErr, ok := callOut[1].Interface().(errors.GraphQLError)