Add pagination for query to get records (#58)

Part of [Create a public laconicd testnet](https://www.notion.so/Create-a-public-laconicd-testnet-896a11bdd8094eff8f1b49c0be0ca3b8)
Handles cerc-io/laconic-console#59

Co-authored-by: IshaVenikar <ishavenikar7@gmail.com>
Reviewed-on: cerc-io/laconicd#58
Co-authored-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
Co-committed-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
This commit is contained in:
2024-09-05 07:33:48 +00:00
committed by nabarun
co-authored by IshaVenikar
parent 94ba057807
commit df43322ef3
8 changed files with 216 additions and 112 deletions
+8 -2
View File
@@ -227,7 +227,7 @@ type Query {
getBondsByIds(ids: [String!]): [Bond]
# Query bonds.
queryBonds(attributes: [KeyValueInput!]): [Bond]
queryBonds: [Bond]
# Query bonds by owner.
queryBondsByOwner(ownerAddresses: [String!]): [OwnerBonds]
@@ -246,6 +246,12 @@ type Query {
# Whether to query all records, not just named ones (false by default).
all: Boolean
# Pagination limit
limit: Int
# Pagination offset
offset: Int
): [Record]
#
@@ -253,7 +259,7 @@ type Query {
#
# Get authorities list.
getAuthorities(owner: String): [Authority]
getAuthorities(owner: String): [Authority]!
# Lookup authority information.
lookupAuthorities(names: [String!]): [AuthorityRecord]!
+71 -81
View File
@@ -183,9 +183,9 @@ type ComplexityRoot struct {
GetStatus func(childComplexity int) int
LookupAuthorities func(childComplexity int, names []string) int
LookupNames func(childComplexity int, names []string) int
QueryBonds func(childComplexity int, attributes []*KeyValueInput) int
QueryBonds func(childComplexity int) int
QueryBondsByOwner func(childComplexity int, ownerAddresses []string) int
QueryRecords func(childComplexity int, attributes []*KeyValueInput, all *bool) int
QueryRecords func(childComplexity int, attributes []*KeyValueInput, all *bool, limit *int, offset *int) int
ResolveNames func(childComplexity int, names []string) int
}
@@ -233,10 +233,10 @@ type QueryResolver interface {
GetStatus(ctx context.Context) (*Status, error)
GetAccounts(ctx context.Context, addresses []string) ([]*Account, error)
GetBondsByIds(ctx context.Context, ids []string) ([]*Bond, error)
QueryBonds(ctx context.Context, attributes []*KeyValueInput) ([]*Bond, error)
QueryBonds(ctx context.Context) ([]*Bond, error)
QueryBondsByOwner(ctx context.Context, ownerAddresses []string) ([]*OwnerBonds, error)
GetRecordsByIds(ctx context.Context, ids []string) ([]*Record, error)
QueryRecords(ctx context.Context, attributes []*KeyValueInput, all *bool) ([]*Record, error)
QueryRecords(ctx context.Context, attributes []*KeyValueInput, all *bool, limit *int, offset *int) ([]*Record, error)
GetAuthorities(ctx context.Context, owner *string) ([]*Authority, error)
LookupAuthorities(ctx context.Context, names []string) ([]*AuthorityRecord, error)
LookupNames(ctx context.Context, names []string) ([]*NameRecord, error)
@@ -844,12 +844,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
args, err := ec.field_Query_queryBonds_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Query.QueryBonds(childComplexity, args["attributes"].([]*KeyValueInput)), true
return e.complexity.Query.QueryBonds(childComplexity), true
case "Query.queryBondsByOwner":
if e.complexity.Query.QueryBondsByOwner == nil {
@@ -873,7 +868,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return 0, false
}
return e.complexity.Query.QueryRecords(childComplexity, args["attributes"].([]*KeyValueInput), args["all"].(*bool)), true
return e.complexity.Query.QueryRecords(childComplexity, args["attributes"].([]*KeyValueInput), args["all"].(*bool), args["limit"].(*int), args["offset"].(*int)), true
case "Query.resolveNames":
if e.complexity.Query.ResolveNames == nil {
@@ -1294,21 +1289,6 @@ func (ec *executionContext) field_Query_queryBondsByOwner_args(ctx context.Conte
return args, nil
}
func (ec *executionContext) field_Query_queryBonds_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 []*KeyValueInput
if tmp, ok := rawArgs["attributes"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("attributes"))
arg0, err = ec.unmarshalOKeyValueInput2ᚕᚖgitᚗvdbᚗtoᚋcercᚑioᚋlaconicdᚋgqlᚐKeyValueInputᚄ(ctx, tmp)
if err != nil {
return nil, err
}
}
args["attributes"] = arg0
return args, nil
}
func (ec *executionContext) field_Query_queryRecords_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
@@ -1330,6 +1310,24 @@ func (ec *executionContext) field_Query_queryRecords_args(ctx context.Context, r
}
}
args["all"] = arg1
var arg2 *int
if tmp, ok := rawArgs["limit"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("limit"))
arg2, err = ec.unmarshalOInt2ᚖint(ctx, tmp)
if err != nil {
return nil, err
}
}
args["limit"] = arg2
var arg3 *int
if tmp, ok := rawArgs["offset"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("offset"))
arg3, err = ec.unmarshalOInt2ᚖint(ctx, tmp)
if err != nil {
return nil, err
}
}
args["offset"] = arg3
return args, nil
}
@@ -4578,7 +4576,7 @@ func (ec *executionContext) _Query_queryBonds(ctx context.Context, field graphql
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().QueryBonds(rctx, fc.Args["attributes"].([]*KeyValueInput))
return ec.resolvers.Query().QueryBonds(rctx)
})
if err != nil {
ec.Error(ctx, err)
@@ -4610,17 +4608,6 @@ func (ec *executionContext) fieldContext_Query_queryBonds(ctx context.Context, f
return nil, fmt.Errorf("no field named %q was found under type Bond", field.Name)
},
}
defer func() {
if r := recover(); r != nil {
err = ec.Recover(ctx, r)
ec.Error(ctx, err)
}
}()
ctx = graphql.WithFieldContext(ctx, fc)
if fc.Args, err = ec.field_Query_queryBonds_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
ec.Error(ctx, err)
return
}
return fc, nil
}
@@ -4766,7 +4753,7 @@ func (ec *executionContext) _Query_queryRecords(ctx context.Context, field graph
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().QueryRecords(rctx, fc.Args["attributes"].([]*KeyValueInput), fc.Args["all"].(*bool))
return ec.resolvers.Query().QueryRecords(rctx, fc.Args["attributes"].([]*KeyValueInput), fc.Args["all"].(*bool), fc.Args["limit"].(*int), fc.Args["offset"].(*int))
})
if err != nil {
ec.Error(ctx, err)
@@ -4843,11 +4830,14 @@ func (ec *executionContext) _Query_getAuthorities(ctx context.Context, field gra
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.([]*Authority)
fc.Result = res
return ec.marshalOAuthority2ᚕᚖgitᚗvdbᚗtoᚋcercᚑioᚋlaconicdᚋgqlᚐAuthority(ctx, field.Selections, res)
return ec.marshalNAuthority2ᚕᚖgitᚗvdbᚗtoᚋcercᚑioᚋlaconicdᚋgqlᚐAuthority(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Query_getAuthorities(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -9581,6 +9571,9 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
}
}()
res = ec._Query_getAuthorities(ctx, field)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
}
@@ -10396,6 +10389,44 @@ func (ec *executionContext) marshalNAttribute2ᚖgitᚗvdbᚗtoᚋcercᚑioᚋla
return ec._Attribute(ctx, sel, v)
}
func (ec *executionContext) marshalNAuthority2ᚕᚖgitᚗvdbᚗtoᚋcercᚑioᚋlaconicdᚋgqlᚐAuthority(ctx context.Context, sel ast.SelectionSet, v []*Authority) graphql.Marshaler {
ret := make(graphql.Array, len(v))
var wg sync.WaitGroup
isLen1 := len(v) == 1
if !isLen1 {
wg.Add(len(v))
}
for i := range v {
i := i
fc := &graphql.FieldContext{
Index: &i,
Result: &v[i],
}
ctx := graphql.WithFieldContext(ctx, fc)
f := func(i int) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = nil
}
}()
if !isLen1 {
defer wg.Done()
}
ret[i] = ec.marshalOAuthority2ᚖgitᚗvdbᚗtoᚋcercᚑioᚋlaconicdᚋgqlᚐAuthority(ctx, sel, v[i])
}
if isLen1 {
f(i)
} else {
go f(i)
}
}
wg.Wait()
return ret
}
func (ec *executionContext) marshalNAuthorityRecord2ᚕᚖgitᚗvdbᚗtoᚋcercᚑioᚋlaconicdᚋgqlᚐAuthorityRecord(ctx context.Context, sel ast.SelectionSet, v []*AuthorityRecord) graphql.Marshaler {
ret := make(graphql.Array, len(v))
var wg sync.WaitGroup
@@ -11231,47 +11262,6 @@ func (ec *executionContext) marshalOAuctionBid2ᚖgitᚗvdbᚗtoᚋcercᚑioᚋl
return ec._AuctionBid(ctx, sel, v)
}
func (ec *executionContext) marshalOAuthority2ᚕᚖgitᚗvdbᚗtoᚋcercᚑioᚋlaconicdᚋgqlᚐAuthority(ctx context.Context, sel ast.SelectionSet, v []*Authority) graphql.Marshaler {
if v == nil {
return graphql.Null
}
ret := make(graphql.Array, len(v))
var wg sync.WaitGroup
isLen1 := len(v) == 1
if !isLen1 {
wg.Add(len(v))
}
for i := range v {
i := i
fc := &graphql.FieldContext{
Index: &i,
Result: &v[i],
}
ctx := graphql.WithFieldContext(ctx, fc)
f := func(i int) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = nil
}
}()
if !isLen1 {
defer wg.Done()
}
ret[i] = ec.marshalOAuthority2ᚖgitᚗvdbᚗtoᚋcercᚑioᚋlaconicdᚋgqlᚐAuthority(ctx, sel, v[i])
}
if isLen1 {
f(i)
} else {
go f(i)
}
}
wg.Wait()
return ret
}
func (ec *executionContext) marshalOAuthority2ᚖgitᚗvdbᚗtoᚋcercᚑioᚋlaconicdᚋgqlᚐAuthority(ctx context.Context, sel ast.SelectionSet, v *Authority) graphql.Marshaler {
if v == nil {
return graphql.Null
+26 -2
View File
@@ -8,6 +8,7 @@ import (
"github.com/cosmos/cosmos-sdk/client"
types "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
@@ -23,6 +24,9 @@ const DefaultLogNumLines = 50
// MaxLogNumLines is the max number of log lines that can be tailed.
const MaxLogNumLines = 1000
// Whether to use default page limit when pagination args are not passed.
const UseDefaultPagination = false
type Resolver struct {
ctx client.Context
logFile string
@@ -136,14 +140,34 @@ func (q queryResolver) LookupNames(ctx context.Context, names []string) ([]*Name
return gqlResponse, nil
}
func (q queryResolver) QueryRecords(ctx context.Context, attributes []*KeyValueInput, all *bool) ([]*Record, error) {
func (q queryResolver) QueryRecords(ctx context.Context, attributes []*KeyValueInput, all *bool, limit *int, offset *int) ([]*Record, error) {
nsQueryClient := registrytypes.NewQueryClient(q.ctx)
var pagination *query.PageRequest
// Use defaults only if limit and offset not provided
// and UseDefaultPagination is true
if limit == nil && offset == nil {
if UseDefaultPagination {
pagination = &query.PageRequest{}
}
} else {
pagination = &query.PageRequest{}
if limit != nil {
pagination.Limit = uint64(*limit)
}
if offset != nil {
pagination.Offset = uint64(*offset)
}
}
res, err := nsQueryClient.Records(
context.Background(),
&registrytypes.QueryRecordsRequest{
Attributes: toRPCAttributes(attributes),
All: (all != nil && *all),
Pagination: pagination,
},
)
if err != nil {
@@ -296,7 +320,7 @@ func (q *queryResolver) GetBond(ctx context.Context, id string) (*Bond, error) {
return getGQLBond(bondResp.GetBond())
}
func (q queryResolver) QueryBonds(ctx context.Context, attributes []*KeyValueInput) ([]*Bond, error) {
func (q queryResolver) QueryBonds(ctx context.Context) ([]*Bond, error) {
bondQueryClient := bondtypes.NewQueryClient(q.ctx)
bonds, err := bondQueryClient.Bonds(context.Background(), &bondtypes.QueryBondsRequest{})
if err != nil {