Revamp the query compilation process.

This commit is contained in:
2024-05-14 11:18:31 +01:00
parent 569867d04b
commit 4f438b7eac
2 changed files with 96 additions and 18 deletions
+34 -15
View File
@@ -2,37 +2,56 @@ package gql
import (
"fmt"
"sync"
"github.com/goccy/go-json"
"github.com/gookit/goutil"
"github.com/gookit/goutil/strutil"
)
var jsonBufferPool = sync.Pool{
New: func() interface{} {
return new([]byte)
},
}
func (b *BaseClient) convertToJSON(v any) []byte {
jsonBuffer := jsonBufferPool.Get().(*[]byte)
defer jsonBufferPool.Put(jsonBuffer)
*jsonBuffer = (*jsonBuffer)[:0]
jsonData, err := json.Marshal(v)
if err != nil {
b.Logger.Error("Can't convert to JSON", map[string]interface{}{"error": err.Error()})
return nil
}
return jsonData
*jsonBuffer = append(*jsonBuffer, jsonData...)
return *jsonBuffer
}
func (b *BaseClient) compileQuery(queryPartials ...any) *Query {
q := &Query{}
var query string
var variables map[string]interface{}
for _, partial := range queryPartials {
switch val := partial.(type) {
case string:
q.Query = val
query = val
case map[string]interface{}:
q.Variables = val
variables = val
}
}
if q.Query == "" {
if query == "" {
b.Logger.Error("Can't compile query", map[string]interface{}{"error": "query is empty"})
return nil
}
q.JsonQuery = b.convertToJSON(q)
return q
jsonQuery := b.convertToJSON(&Query{Query: query, Variables: variables})
return &Query{
Query: query,
Variables: variables,
JsonQuery: jsonQuery,
}
}
func (b *BaseClient) Query(query string, variables map[string]interface{}, headers map[string]interface{}) (any, error) {
@@ -52,8 +71,7 @@ func (b *BaseClient) Query(query string, variables map[string]interface{}, heade
if (enableCache || b.cache_global) && strutil.HasPrefix(compiledQuery.Query, "query") {
b.Logger.Debug("Cache enabled", nil)
queryHash = calculateHash(compiledQuery)
cachedValue := b.cacheLookup(queryHash)
if cachedValue != nil {
if cachedValue := b.cacheLookup(queryHash); cachedValue != nil {
b.Logger.Debug("Cache hit", map[string]interface{}{"query": compiledQuery})
return cachedValue, nil
}
@@ -76,7 +94,6 @@ func (b *BaseClient) Query(query string, variables map[string]interface{}, heade
}(),
Retries: enableRetries || b.retries_enable,
}
defer func() { q = nil }()
rv, err := q.executeQuery()
if err != nil {
@@ -84,8 +101,7 @@ func (b *BaseClient) Query(query string, variables map[string]interface{}, heade
return nil, err
}
returnedValue, err := q.decodeResponse(rv)
return returnedValue, err
return q.decodeResponse(rv)
}
func (q *Query) parseHeadersAndVariables(headers map[string]interface{}) (enableCache, enableRetries, recompileRequired bool) {
@@ -97,9 +113,12 @@ func (q *Query) parseHeadersAndVariables(headers map[string]interface{}) (enable
varEnableRetries, _ := goutil.ToBool(searchForKeysInMapStringInterface(q.Variables, "gqlretries"))
enableCache = enableCache || varEnableCache
enableRetries = enableRetries || varEnableRetries
delete(q.Variables, "gqlcache")
delete(q.Variables, "gqlretries")
recompileRequired = true
if varEnableCache || varEnableRetries {
delete(q.Variables, "gqlcache")
delete(q.Variables, "gqlretries")
recompileRequired = true
}
}
return enableCache, enableRetries, recompileRequired