combine query params filters
This commit is contained in:
parent
91fbd1cdaf
commit
5b03c9e899
|
@ -111,12 +111,61 @@ type OperationQuery struct {
|
|||
Pagination pagination.Pagination
|
||||
TxHash string
|
||||
Address string
|
||||
ChainID *vaa.ChainID
|
||||
SourceChainID *vaa.ChainID
|
||||
TargetChainID *vaa.ChainID
|
||||
AppID string
|
||||
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
|
||||
|
@ -199,7 +248,7 @@ func findOperationsIdByChain(ctx context.Context, db *mongo.Database, chainId va
|
|||
}
|
||||
return ids, nil
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
*/
|
||||
|
||||
// findOperationsIdByAddress returns all operations filtered by address.
|
||||
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.
|
||||
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)
|
||||
matchByTxHash := r.matchOperationByTxHash(ctx, query.TxHash)
|
||||
pipeline = append(pipeline, matchByTxHash)
|
||||
} else if query.ChainID != nil {
|
||||
ids, err := findOperationsIdByChain(ctx, r.db, query.ChainID, query.ChainID, false)
|
||||
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 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)
|
||||
} else if query.SourceChainID != nil || query.TargetChainID != nil || query.AppID != "" {
|
||||
// find all ids that match by source and target chain id
|
||||
ids, err := r.findOpsIdByChainAndAppId(ctx, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -34,13 +34,11 @@ func (s *Service) FindById(ctx context.Context, chainID vaa.ChainID,
|
|||
type OperationFilter struct {
|
||||
TxHash *types.TxHash
|
||||
Address string
|
||||
ChainID *vaa.ChainID
|
||||
SourceChainID *vaa.ChainID
|
||||
TargetChainID *vaa.ChainID
|
||||
AppID string
|
||||
ExclusiveAppId bool
|
||||
Pagination pagination.Pagination
|
||||
PayloadType *float64
|
||||
}
|
||||
|
||||
// FindAll returns all operations filtered by q.
|
||||
|
@ -54,12 +52,10 @@ func (s *Service) FindAll(ctx context.Context, filter OperationFilter) ([]*Opera
|
|||
TxHash: txHash,
|
||||
Address: filter.Address,
|
||||
Pagination: filter.Pagination,
|
||||
ChainID: filter.ChainID,
|
||||
SourceChainID: filter.SourceChainID,
|
||||
TargetChainID: filter.TargetChainID,
|
||||
AppID: filter.AppID,
|
||||
ExclusiveAppId: filter.ExclusiveAppId,
|
||||
PayloadType: filter.PayloadType,
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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) {
|
||||
// get the timeSpan from query params
|
||||
timeSpanStr := c.Query("timeSpan", "1d")
|
||||
|
|
|
@ -54,17 +54,19 @@ func (c *Controller) FindAll(ctx *fiber.Ctx) error {
|
|||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
sourceChainID, err := middleware.ExtractSourceChain(ctx, c.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
targeChainID, err := middleware.ExtractTargetChain(ctx, c.logger)
|
||||
targetChain, err := middleware.ExtractTargetChain(ctx, c.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -75,39 +77,21 @@ func (c *Controller) FindAll(ctx *fiber.Ctx) error {
|
|||
return err
|
||||
}
|
||||
|
||||
payloadType, err := middleware.ExtractPayloadType(ctx, c.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
searchBySourceTargetChain := sourceChain != nil || targetChain != nil
|
||||
searchByAppId := appID != ""
|
||||
|
||||
searchByAddress := address != ""
|
||||
searchByTxHash := txHash != nil && txHash.String() != ""
|
||||
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)
|
||||
if (searchByAddress || searchByTxHash) && (searchBySourceTargetChain || searchByAppId) {
|
||||
return response.NewInvalidParamError(ctx, "address/txHash cannot be combined with sourceChain/targetChain/appId query filter", nil)
|
||||
}
|
||||
|
||||
filter := operations.OperationFilter{
|
||||
TxHash: txHash,
|
||||
Address: address,
|
||||
ChainID: chainID,
|
||||
SourceChainID: sourceChainID,
|
||||
TargetChainID: targeChainID,
|
||||
SourceChainID: sourceChain,
|
||||
TargetChainID: targetChain,
|
||||
AppID: appID,
|
||||
ExclusiveAppId: exclusiveAppId,
|
||||
Pagination: *pagination,
|
||||
PayloadType: payloadType,
|
||||
}
|
||||
|
||||
// Find operations by q search param.
|
||||
|
|
Loading…
Reference in New Issue