101 lines
2.3 KiB
Go
101 lines
2.3 KiB
Go
package graphql
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type Query[ReturnType any, Params any] struct {
|
|
c *Client
|
|
gqltype string
|
|
containerLayers []string
|
|
|
|
additionalPayloadParams map[string]interface{}
|
|
additionalQueryParams map[string]interface{}
|
|
|
|
maxPageSize int
|
|
}
|
|
|
|
func NewQuery[ReturnType any, Params any](
|
|
c *Client,
|
|
gqlType string,
|
|
containerLayers []string,
|
|
) *Query[ReturnType, Params] {
|
|
return &Query[ReturnType, Params]{
|
|
c: c,
|
|
gqltype: gqlType,
|
|
containerLayers: containerLayers,
|
|
|
|
additionalPayloadParams: make(map[string]interface{}),
|
|
additionalQueryParams: make(map[string]interface{}),
|
|
maxPageSize: 0,
|
|
}
|
|
}
|
|
|
|
func (r *Query[ReturnType, Params]) WithPayloadParam(
|
|
name string,
|
|
value interface{},
|
|
) *Query[ReturnType, Params] {
|
|
r.additionalPayloadParams[name] = value
|
|
return r
|
|
}
|
|
|
|
func (r *Query[ReturnType, Params]) WithQueryParam(
|
|
name string,
|
|
value interface{},
|
|
) *Query[ReturnType, Params] {
|
|
r.additionalQueryParams[name] = value
|
|
return r
|
|
}
|
|
|
|
func (r *Query[ReturnType, Params]) WithMaxPageSize(maxPageSize int) *Query[ReturnType, Params] {
|
|
r.maxPageSize = maxPageSize
|
|
return r
|
|
}
|
|
|
|
func (r *Query[ReturnType, Params]) GetPageSize() int {
|
|
t := reflect.TypeOf((*ReturnType)(nil)).Elem()
|
|
if t.Kind() == reflect.Slice {
|
|
t = t.Elem()
|
|
}
|
|
complexity := GetTypeComplexity(t)
|
|
maxComplexity := r.c.MaxQueryComplexity()
|
|
layers := len(r.containerLayers)
|
|
computedPageSize := (maxComplexity - layers - 1) / complexity
|
|
|
|
if r.maxPageSize > 0 && r.maxPageSize < computedPageSize {
|
|
return r.maxPageSize
|
|
}
|
|
return computedPageSize
|
|
}
|
|
|
|
func (r *Query[ReturnType, Params]) Get(ctx context.Context, params Params) (ReturnType, error) {
|
|
|
|
paramsMap := convertParamsToMap(params)
|
|
for k, v := range r.additionalPayloadParams {
|
|
paramsMap[k] = v
|
|
}
|
|
gqltype := r.gqltype
|
|
if len(paramsMap) > 0 {
|
|
keys := make([]string, 0, len(paramsMap))
|
|
for k := range paramsMap {
|
|
keys = append(keys, fmt.Sprintf("%s:$%s", k, k))
|
|
}
|
|
gqltype = fmt.Sprintf("%s(%s)", gqltype, strings.Join(keys, ","))
|
|
}
|
|
for k, v := range r.additionalQueryParams {
|
|
paramsMap[k] = v
|
|
}
|
|
q := NewPayload[ReturnType](gqltype, r.containerLayers...)
|
|
err := r.c.Query(ctx, q, paramsMap)
|
|
if err != nil {
|
|
var res ReturnType
|
|
return res, errors.Wrap(err, "querying records")
|
|
}
|
|
return q.GetValue(), nil
|
|
}
|