Files
upstream-corteza/server/pkg/dal/iterator.go
upstream-mirror 7e385fc126
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:22:23 +05:00

120 lines
2.5 KiB
Go

package dal
import (
"context"
"encoding/json"
"io"
"github.com/cortezaproject/corteza/server/pkg/filter"
)
type (
// Iterator provides an interface for loading data from the underlying store
Iterator interface {
Next(ctx context.Context) bool
More(uint, ValueGetter) error
Err() error
Scan(ValueSetter) error
Close() error
BackCursor(ValueGetter) (*filter.PagingCursor, error)
ForwardCursor(ValueGetter) (*filter.PagingCursor, error)
// // -1 means unknown
// Total() int
// Cursor() any
// // ... do we need anything else here?
}
iterator interface {
Preload(context.Context, uint, *filter.PagingCursor) error
Sorting() filter.SortExprSet
}
)
// IteratorEncodeJSON helper function that encodes each item from the iterator as JSON
// and writes it to th given io.Writer.
//
// target initialization function is intentionally used to avoid use of reflection
func IteratorEncodeJSON(ctx context.Context, w io.Writer, iter Iterator, initTarget func() ValueSetter) (err error) {
var (
target ValueSetter
firstOut = false
)
for iter.Next(ctx) {
if err = iter.Err(); err != nil {
return
}
if firstOut {
if _, err = w.Write([]byte(`,`)); err != nil {
return
}
}
firstOut = true
target = initTarget()
if err = iter.Scan(target); err != nil {
return
}
err = json.NewEncoder(w).Encode(target)
if err != nil {
return
}
}
return
}
// PreLoadCursor into iterator and check it exist then return the cursor
// @todo this should be move to the Iterator
func PreLoadCursor(ctx context.Context, iter Iterator, limit uint, reverse bool, r ValueGetter, fx func(Iterator) (bool, error)) (out *filter.PagingCursor, err error) {
makeCursor := func() (*filter.PagingCursor, error) {
if reverse {
return iter.BackCursor(r)
} else {
return iter.ForwardCursor(r)
}
}
out, err = makeCursor()
if err != nil {
return
}
err = iter.(iterator).Preload(ctx, limit, out)
if err != nil {
return nil, nil
}
for {
if !iter.Next(ctx) {
out = nil
return
}
ok, err := fx(iter)
if err != nil {
return nil, err
}
if ok {
return out, err
// // @todo Skip the things we don't have access to; could cause some edge cases so probably not
// // It adds some performance since we skip unneeded stuff but could some records change in the mean time?
// // return makeCursor()
}
}
}
// IteratorSorting return iterator sorting
// @todo this should be move to the Iterator
func IteratorSorting(iter Iterator) filter.SortExprSet {
return iter.(iterator).Sorting()
}