goext/wmo/queryList.go

100 lines
2.2 KiB
Go
Raw Permalink Normal View History

2023-06-06 21:33:49 +02:00
package wmo
import (
"context"
"go.mongodb.org/mongo-driver/bson"
ct "gogs.mikescher.com/BlackForestBytes/goext/cursortoken"
)
func (c *Coll[TData]) List(ctx context.Context, filter ct.Filter, pageSize *int, inTok ct.CursorToken) ([]TData, ct.CursorToken, error) {
if inTok.Mode == ct.CTMEnd {
return make([]TData, 0), ct.End(), nil
}
pipeline := filter.FilterQuery()
2023-06-07 10:42:56 +02:00
pf1, pd1, pf2, pd2 := filter.Pagination()
sortPrimary := pf1
sortDirPrimary := pd1
sortSecondary := &pf2
sortDirSecondary := &pd2
if pf1 == pf2 {
sortSecondary = nil
sortDirSecondary = nil
}
2023-06-06 21:33:49 +02:00
paginationPipeline, err := CreatePagination(c, inTok, sortPrimary, sortDirPrimary, sortSecondary, sortDirSecondary, pageSize)
if err != nil {
return nil, ct.CursorToken{}, err
}
pipeline = append(pipeline, paginationPipeline...)
cursor, err := c.coll.Aggregate(ctx, pipeline)
if err != nil {
return nil, ct.CursorToken{}, err
}
2023-06-10 16:22:14 +02:00
// fast branch
if pageSize == nil {
entries, err := c.decodeAll(ctx, cursor)
if err != nil {
return nil, ct.CursorToken{}, err
}
return entries, ct.End(), nil
}
2023-06-07 17:57:03 +02:00
entities := make([]TData, 0, cursor.RemainingBatchLength())
2023-06-06 21:33:49 +02:00
for (pageSize == nil || len(entities) != *pageSize) && cursor.Next(ctx) {
var entry TData
2023-06-10 16:22:14 +02:00
entry, err = c.decodeSingle(ctx, cursor)
2023-06-06 21:33:49 +02:00
if err != nil {
return nil, ct.CursorToken{}, err
}
entities = append(entities, entry)
}
2023-06-07 17:57:03 +02:00
if pageSize == nil || len(entities) < *pageSize || !cursor.TryNext(ctx) {
2023-06-06 21:33:49 +02:00
return entities, ct.End(), nil
}
last := entities[len(entities)-1]
2023-06-10 18:35:56 +02:00
c.EnsureInitializedReflection(last)
2023-06-07 17:57:03 +02:00
nextToken, err := c.createToken(sortPrimary, sortDirPrimary, sortSecondary, sortDirSecondary, last, pageSize)
if err != nil {
return nil, ct.CursorToken{}, err
}
2023-06-06 21:33:49 +02:00
return entities, nextToken, nil
}
2023-06-07 11:28:07 +02:00
type countRes struct {
Count int64 `bson:"c"`
}
2023-06-06 21:33:49 +02:00
func (c *Coll[TData]) Count(ctx context.Context, filter ct.Filter) (int64, error) {
pipeline := filter.FilterQuery()
pipeline = append(pipeline, bson.D{{Key: "$count", Value: "c"}})
cursor, err := c.coll.Aggregate(ctx, pipeline)
if err != nil {
return 0, err
}
if cursor.Next(ctx) {
2023-06-07 11:28:07 +02:00
v := countRes{}
2023-06-06 21:33:49 +02:00
err = cursor.Decode(&v)
if err != nil {
return 0, err
}
return v.Count, nil
}
return 0, nil
}