v0.0.304 add support for WithModifyingPipeline
to wmo
Some checks failed
Build Docker and Deploy / Run goext test-suite (push) Failing after 1m22s
Some checks failed
Build Docker and Deploy / Run goext test-suite (push) Failing after 1m22s
This commit is contained in:
@@ -34,7 +34,7 @@ func (c *Coll[TData]) List(ctx context.Context, filter ct.Filter, pageSize *int,
|
||||
sortDirSecondary = nil
|
||||
}
|
||||
|
||||
paginationPipeline, err := CreatePagination(c, inTok, sortPrimary, sortDirPrimary, sortSecondary, sortDirSecondary, pageSize)
|
||||
paginationPipeline, err := createPaginationPipeline(c, inTok, sortPrimary, sortDirPrimary, sortSecondary, sortDirSecondary, pageSize)
|
||||
if err != nil {
|
||||
return nil, ct.CursorToken{}, exerr.
|
||||
Wrap(err, "failed to create pagination").
|
||||
@@ -50,6 +50,7 @@ func (c *Coll[TData]) List(ctx context.Context, filter ct.Filter, pageSize *int,
|
||||
}
|
||||
|
||||
pipeline = append(pipeline, paginationPipeline...)
|
||||
pipeline = append(pipeline, c.extraModPipeline...)
|
||||
|
||||
cursor, err := c.coll.Aggregate(ctx, pipeline)
|
||||
if err != nil {
|
||||
@@ -130,3 +131,83 @@ func (c *Coll[TData]) ListWithCount(ctx context.Context, filter ct.Filter, pageS
|
||||
}
|
||||
return data, token, count, nil
|
||||
}
|
||||
|
||||
func createPaginationPipeline[TData any](coll *Coll[TData], token ct.CursorToken, fieldPrimary string, sortPrimary ct.SortDirection, fieldSecondary *string, sortSecondary *ct.SortDirection, pageSize *int) ([]bson.D, error) {
|
||||
|
||||
cond := bson.A{}
|
||||
sort := bson.D{}
|
||||
|
||||
valuePrimary, err := coll.getTokenValueAsMongoType(token.ValuePrimary, fieldPrimary)
|
||||
if err != nil {
|
||||
return nil, exerr.Wrap(err, "failed to get (primary) token-value as mongo-type").Build()
|
||||
}
|
||||
|
||||
if sortPrimary == ct.SortASC {
|
||||
// We sort ASC on <field> - so we want all entries newer ($gt) than the $primary
|
||||
cond = append(cond, bson.M{fieldPrimary: bson.M{"$gt": valuePrimary}})
|
||||
sort = append(sort, bson.E{Key: fieldPrimary, Value: +1})
|
||||
} else if sortPrimary == ct.SortDESC {
|
||||
// We sort DESC on <field> - so we want all entries older ($lt) than the $primary
|
||||
cond = append(cond, bson.M{fieldPrimary: bson.M{"$lt": valuePrimary}})
|
||||
sort = append(sort, bson.E{Key: fieldPrimary, Value: -1})
|
||||
}
|
||||
|
||||
if fieldSecondary != nil && sortSecondary != nil && *fieldSecondary != fieldPrimary {
|
||||
|
||||
valueSecondary, err := coll.getTokenValueAsMongoType(token.ValueSecondary, *fieldSecondary)
|
||||
if err != nil {
|
||||
return nil, exerr.Wrap(err, "failed to get (secondary) token-value as mongo-type").Build()
|
||||
}
|
||||
|
||||
if *sortSecondary == ct.SortASC {
|
||||
|
||||
// the conflict-resolution condition, for entries with the _same_ <field> as the $primary we take the ones with a greater $secondary (= newer)
|
||||
cond = append(cond, bson.M{"$and": bson.A{
|
||||
bson.M{fieldPrimary: valuePrimary},
|
||||
bson.M{*fieldSecondary: bson.M{"$gt": valueSecondary}},
|
||||
}})
|
||||
|
||||
sort = append(sort, bson.E{Key: fieldPrimary, Value: +1})
|
||||
|
||||
} else if *sortSecondary == ct.SortDESC {
|
||||
|
||||
// the conflict-resolution condition, for entries with the _same_ <field> as the $primary we take the ones with a smaller $secondary (= older)
|
||||
cond = append(cond, bson.M{"$and": bson.A{
|
||||
bson.M{fieldPrimary: valuePrimary},
|
||||
bson.M{*fieldSecondary: bson.M{"$lt": valueSecondary}},
|
||||
}})
|
||||
|
||||
sort = append(sort, bson.E{Key: fieldPrimary, Value: -1})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pipeline := make([]bson.D, 0, 3)
|
||||
|
||||
if token.Mode == ct.CTMStart {
|
||||
|
||||
// no gt/lt condition
|
||||
|
||||
} else if token.Mode == ct.CTMNormal {
|
||||
|
||||
pipeline = append(pipeline, bson.D{{Key: "$match", Value: bson.M{"$or": cond}}})
|
||||
|
||||
} else if token.Mode == ct.CTMEnd {
|
||||
|
||||
// false
|
||||
pipeline = append(pipeline, bson.D{{Key: "$match", Value: bson.M{"$expr": bson.M{"$eq": bson.A{"1", "0"}}}}})
|
||||
|
||||
} else {
|
||||
|
||||
return nil, exerr.New(exerr.TypeInternal, "unknown ct mode: "+string(token.Mode)).Any("token.Mode", token.Mode).Build()
|
||||
|
||||
}
|
||||
|
||||
pipeline = append(pipeline, bson.D{{Key: "$sort", Value: sort}})
|
||||
|
||||
if pageSize != nil {
|
||||
pipeline = append(pipeline, bson.D{{Key: "$limit", Value: int64(*pageSize + 1)}})
|
||||
}
|
||||
|
||||
return pipeline, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user