combine query params filters
This commit is contained in:
parent
91fbd1cdaf
commit
5b03c9e899
|
@ -111,12 +111,61 @@ type OperationQuery struct {
|
||||||
Pagination pagination.Pagination
|
Pagination pagination.Pagination
|
||||||
TxHash string
|
TxHash string
|
||||||
Address string
|
Address string
|
||||||
ChainID *vaa.ChainID
|
|
||||||
SourceChainID *vaa.ChainID
|
SourceChainID *vaa.ChainID
|
||||||
TargetChainID *vaa.ChainID
|
TargetChainID *vaa.ChainID
|
||||||
AppID string
|
AppID string
|
||||||
ExclusiveAppId bool
|
ExclusiveAppId bool
|
||||||
PayloadType *float64
|
}
|
||||||
|
|
||||||
|
func buildQueryOperationsByChain(sourceChainID, targetChainID *vaa.ChainID, strict bool) bson.D {
|
||||||
|
var allMatch bson.A
|
||||||
|
|
||||||
|
if sourceChainID != nil {
|
||||||
|
matchSourceChain := bson.D{{Key: "$or", Value: bson.A{
|
||||||
|
bson.D{{Key: "rawStandardizedProperties.fromChain", Value: bson.M{"$eq": sourceChainID}}},
|
||||||
|
bson.D{{Key: "standardizedProperties.fromChain", Value: bson.M{"$eq": sourceChainID}}},
|
||||||
|
}}}
|
||||||
|
allMatch = append(allMatch, matchSourceChain)
|
||||||
|
}
|
||||||
|
if targetChainID != nil {
|
||||||
|
matchTargetChain := bson.D{{Key: "$or", Value: bson.A{
|
||||||
|
bson.D{{Key: "parsedPayload.toChain", Value: bson.M{"$eq": targetChainID}}},
|
||||||
|
bson.D{{Key: "parsedPayload.targetChainId", Value: bson.M{"$eq": targetChainID}}},
|
||||||
|
bson.D{{Key: "standardizedProperties.toChain", Value: bson.M{"$eq": targetChainID}}},
|
||||||
|
bson.D{{Key: "rawStandardizedProperties.toChain", Value: bson.M{"$eq": targetChainID}}},
|
||||||
|
}}}
|
||||||
|
allMatch = append(allMatch, matchTargetChain)
|
||||||
|
}
|
||||||
|
|
||||||
|
var matchParsedVaa bson.D
|
||||||
|
if strict {
|
||||||
|
matchParsedVaa = bson.D{{Key: "$match", Value: bson.D{{Key: "$and", Value: allMatch}}}}
|
||||||
|
} else {
|
||||||
|
matchParsedVaa = bson.D{{Key: "$match", Value: bson.D{{Key: "$or", Value: allMatch}}}}
|
||||||
|
}
|
||||||
|
return matchParsedVaa
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildQueryOperationsByAppID(appID string, exclusive bool) bson.D {
|
||||||
|
|
||||||
|
if appID == "" {
|
||||||
|
return bson.D{{Key: "$match", Value: bson.M{}}}
|
||||||
|
}
|
||||||
|
|
||||||
|
var appIdsCondition interface{}
|
||||||
|
if exclusive {
|
||||||
|
appIdsCondition = bson.M{"$eq": []string{appID}}
|
||||||
|
} else {
|
||||||
|
appIdsCondition = bson.M{"$in": []string{appID}}
|
||||||
|
}
|
||||||
|
|
||||||
|
matchParsedVaa := bson.D{{Key: "$match", Value: bson.D{{Key: "$or", Value: bson.A{
|
||||||
|
bson.D{{Key: "appIds", Value: appIdsCondition}},
|
||||||
|
bson.D{{Key: "rawStandardizedProperties.appIds", Value: appIdsCondition}},
|
||||||
|
bson.D{{Key: "standardizedProperties.appIds", Value: appIdsCondition}},
|
||||||
|
}}}}}
|
||||||
|
|
||||||
|
return matchParsedVaa
|
||||||
}
|
}
|
||||||
|
|
||||||
// strict flag is to force that both source and target chain id must match
|
// strict flag is to force that both source and target chain id must match
|
||||||
|
@ -199,7 +248,7 @@ func findOperationsIdByChain(ctx context.Context, db *mongo.Database, chainId va
|
||||||
}
|
}
|
||||||
return ids, nil
|
return ids, nil
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
func findOperationsIdByAppID(ctx context.Context, db *mongo.Database, appID string, exclusive bool) ([]string, error) {
|
func findOperationsIdByAppID(ctx context.Context, db *mongo.Database, appID string, exclusive bool) ([]string, error) {
|
||||||
|
|
||||||
|
@ -232,6 +281,7 @@ func findOperationsIdByAppID(ctx context.Context, db *mongo.Database, appID stri
|
||||||
}
|
}
|
||||||
return ids, nil
|
return ids, nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// findOperationsIdByAddress returns all operations filtered by address.
|
// findOperationsIdByAddress returns all operations filtered by address.
|
||||||
func findOperationsIdByAddress(ctx context.Context, db *mongo.Database, address string, pagination *pagination.Pagination) ([]string, error) {
|
func findOperationsIdByAddress(ctx context.Context, db *mongo.Database, address string, pagination *pagination.Pagination) ([]string, error) {
|
||||||
|
@ -307,6 +357,35 @@ func (r *Repository) matchOperationByTxHash(ctx context.Context, txHash string)
|
||||||
}}}}}
|
}}}}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Repository) findOpsIdByChainAndAppId(ctx context.Context, query OperationQuery) ([]string, error) {
|
||||||
|
|
||||||
|
var pipeline mongo.Pipeline
|
||||||
|
|
||||||
|
if query.SourceChainID != nil || query.TargetChainID != nil {
|
||||||
|
matchBySourceTargetChain := buildQueryOperationsByChain(query.SourceChainID, query.TargetChainID, true)
|
||||||
|
pipeline = append(pipeline, matchBySourceTargetChain)
|
||||||
|
}
|
||||||
|
if len(query.AppID) > 0 {
|
||||||
|
matchByAppId := buildQueryOperationsByAppID(query.AppID, query.ExclusiveAppId)
|
||||||
|
pipeline = append(pipeline, matchByAppId)
|
||||||
|
}
|
||||||
|
|
||||||
|
cur, err := r.db.Collection("parsedVaa").Aggregate(ctx, pipeline)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var documents []mongoID
|
||||||
|
err = cur.All(ctx, &documents)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var ids []string
|
||||||
|
for _, doc := range documents {
|
||||||
|
ids = append(ids, doc.Id)
|
||||||
|
}
|
||||||
|
return ids, nil
|
||||||
|
}
|
||||||
|
|
||||||
// FindAll returns all operations filtered by q.
|
// FindAll returns all operations filtered by q.
|
||||||
func (r *Repository) FindAll(ctx context.Context, query OperationQuery) ([]*OperationDto, error) {
|
func (r *Repository) FindAll(ctx context.Context, query OperationQuery) ([]*OperationDto, error) {
|
||||||
|
|
||||||
|
@ -333,26 +412,9 @@ func (r *Repository) FindAll(ctx context.Context, query OperationQuery) ([]*Oper
|
||||||
// match operation by txHash (source tx and destination tx)
|
// match operation by txHash (source tx and destination tx)
|
||||||
matchByTxHash := r.matchOperationByTxHash(ctx, query.TxHash)
|
matchByTxHash := r.matchOperationByTxHash(ctx, query.TxHash)
|
||||||
pipeline = append(pipeline, matchByTxHash)
|
pipeline = append(pipeline, matchByTxHash)
|
||||||
} else if query.ChainID != nil {
|
} else if query.SourceChainID != nil || query.TargetChainID != nil || query.AppID != "" {
|
||||||
ids, err := findOperationsIdByChain(ctx, r.db, query.ChainID, query.ChainID, false)
|
// find all ids that match by source and target chain id
|
||||||
if err != nil {
|
ids, err := r.findOpsIdByChainAndAppId(ctx, query)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(ids) == 0 {
|
|
||||||
return []*OperationDto{}, nil
|
|
||||||
}
|
|
||||||
pipeline = append(pipeline, bson.D{{Key: "$match", Value: bson.D{{Key: "_id", Value: bson.D{{Key: "$in", Value: ids}}}}}})
|
|
||||||
} else if query.SourceChainID != nil || query.TargetChainID != nil {
|
|
||||||
ids, err := findOperationsIdByChain(ctx, r.db, query.SourceChainID, query.TargetChainID, true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(ids) == 0 {
|
|
||||||
return []*OperationDto{}, nil
|
|
||||||
}
|
|
||||||
pipeline = append(pipeline, bson.D{{Key: "$match", Value: bson.D{{Key: "_id", Value: bson.D{{Key: "$in", Value: ids}}}}}})
|
|
||||||
} else if len(query.AppID) > 0 {
|
|
||||||
ids, err := findOperationsIdByAppID(ctx, r.db, query.AppID, query.ExclusiveAppId)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,13 +34,11 @@ func (s *Service) FindById(ctx context.Context, chainID vaa.ChainID,
|
||||||
type OperationFilter struct {
|
type OperationFilter struct {
|
||||||
TxHash *types.TxHash
|
TxHash *types.TxHash
|
||||||
Address string
|
Address string
|
||||||
ChainID *vaa.ChainID
|
|
||||||
SourceChainID *vaa.ChainID
|
SourceChainID *vaa.ChainID
|
||||||
TargetChainID *vaa.ChainID
|
TargetChainID *vaa.ChainID
|
||||||
AppID string
|
AppID string
|
||||||
ExclusiveAppId bool
|
ExclusiveAppId bool
|
||||||
Pagination pagination.Pagination
|
Pagination pagination.Pagination
|
||||||
PayloadType *float64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindAll returns all operations filtered by q.
|
// FindAll returns all operations filtered by q.
|
||||||
|
@ -54,12 +52,10 @@ func (s *Service) FindAll(ctx context.Context, filter OperationFilter) ([]*Opera
|
||||||
TxHash: txHash,
|
TxHash: txHash,
|
||||||
Address: filter.Address,
|
Address: filter.Address,
|
||||||
Pagination: filter.Pagination,
|
Pagination: filter.Pagination,
|
||||||
ChainID: filter.ChainID,
|
|
||||||
SourceChainID: filter.SourceChainID,
|
SourceChainID: filter.SourceChainID,
|
||||||
TargetChainID: filter.TargetChainID,
|
TargetChainID: filter.TargetChainID,
|
||||||
AppID: filter.AppID,
|
AppID: filter.AppID,
|
||||||
ExclusiveAppId: filter.ExclusiveAppId,
|
ExclusiveAppId: filter.ExclusiveAppId,
|
||||||
PayloadType: filter.PayloadType,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
operations, err := s.repo.FindAll(ctx, operationQuery)
|
operations, err := s.repo.FindAll(ctx, operationQuery)
|
||||||
|
|
|
@ -299,24 +299,6 @@ func ExtractExclusiveAppId(c *fiber.Ctx, l *zap.Logger) (bool, error) {
|
||||||
return strconv.ParseBool(query)
|
return strconv.ParseBool(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractPayloadType(c *fiber.Ctx, l *zap.Logger) (*float64, error) {
|
|
||||||
payloadTypeParam := c.Query("payloadType")
|
|
||||||
if payloadTypeParam == "" {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
payloadType, err := strconv.ParseFloat(payloadTypeParam, 64)
|
|
||||||
if err != nil {
|
|
||||||
requestID := fmt.Sprintf("%v", c.Locals("requestid"))
|
|
||||||
l.Error("failed to parse payload type parameter",
|
|
||||||
zap.Error(err),
|
|
||||||
zap.String("requestID", requestID),
|
|
||||||
)
|
|
||||||
return nil, response.NewInvalidParamError(c, "INVALID PAYLOAD TYPE", errors.WithStack(err))
|
|
||||||
}
|
|
||||||
return &payloadType, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExtractTimeSpan(c *fiber.Ctx, l *zap.Logger) (string, error) {
|
func ExtractTimeSpan(c *fiber.Ctx, l *zap.Logger) (string, error) {
|
||||||
// get the timeSpan from query params
|
// get the timeSpan from query params
|
||||||
timeSpanStr := c.Query("timeSpan", "1d")
|
timeSpanStr := c.Query("timeSpan", "1d")
|
||||||
|
|
|
@ -54,17 +54,19 @@ func (c *Controller) FindAll(ctx *fiber.Ctx) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
chainID, err := middleware.ExtractChain(ctx, c.logger)
|
searchByAddress := address != ""
|
||||||
|
searchByTxHash := txHash != nil && txHash.String() != ""
|
||||||
|
|
||||||
|
if searchByAddress && searchByTxHash {
|
||||||
|
return response.NewInvalidParamError(ctx, "address and txHash cannot be used at the same time", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceChain, err := middleware.ExtractSourceChain(ctx, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceChainID, err := middleware.ExtractSourceChain(ctx, c.logger)
|
targetChain, err := middleware.ExtractTargetChain(ctx, c.logger)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
targeChainID, err := middleware.ExtractTargetChain(ctx, c.logger)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -75,39 +77,21 @@ func (c *Controller) FindAll(ctx *fiber.Ctx) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
payloadType, err := middleware.ExtractPayloadType(ctx, c.logger)
|
searchBySourceTargetChain := sourceChain != nil || targetChain != nil
|
||||||
if err != nil {
|
searchByAppId := appID != ""
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
searchByAddress := address != ""
|
if (searchByAddress || searchByTxHash) && (searchBySourceTargetChain || searchByAppId) {
|
||||||
searchByTxHash := txHash != nil && txHash.String() != ""
|
return response.NewInvalidParamError(ctx, "address/txHash cannot be combined with sourceChain/targetChain/appId query filter", nil)
|
||||||
searchByChainId := chainID != nil
|
|
||||||
searchBySourceAndTargetChain := sourceChainID != nil && targeChainID != nil
|
|
||||||
searchByAppID := len(appID) > 0
|
|
||||||
searchByPayloadType := payloadType != nil
|
|
||||||
searchCriteria := []bool{searchByAddress, searchByTxHash, searchByChainId, searchByAppID, searchByPayloadType, searchBySourceAndTargetChain}
|
|
||||||
|
|
||||||
searchCriteriaCount := 0
|
|
||||||
for _, sc := range searchCriteria {
|
|
||||||
if sc {
|
|
||||||
searchCriteriaCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if searchCriteriaCount > 1 {
|
|
||||||
return response.NewInvalidParamError(ctx, "only one search-criteria can be used at once", nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filter := operations.OperationFilter{
|
filter := operations.OperationFilter{
|
||||||
TxHash: txHash,
|
TxHash: txHash,
|
||||||
Address: address,
|
Address: address,
|
||||||
ChainID: chainID,
|
SourceChainID: sourceChain,
|
||||||
SourceChainID: sourceChainID,
|
TargetChainID: targetChain,
|
||||||
TargetChainID: targeChainID,
|
|
||||||
AppID: appID,
|
AppID: appID,
|
||||||
ExclusiveAppId: exclusiveAppId,
|
ExclusiveAppId: exclusiveAppId,
|
||||||
Pagination: *pagination,
|
Pagination: *pagination,
|
||||||
PayloadType: payloadType,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find operations by q search param.
|
// Find operations by q search param.
|
||||||
|
|
Loading…
Reference in New Issue