Files
oslstats/internal/db/getlist.go
2026-02-08 20:52:58 +11:00

72 lines
1.4 KiB
Go

package db
import (
"context"
"database/sql"
"github.com/pkg/errors"
"github.com/uptrace/bun"
)
type listgetter[T any] struct {
q *bun.SelectQuery
items *[]*T
pageOpts *PageOpts
defaults *PageOpts
}
type List[T any] struct {
Items []*T
Total int
PageOpts PageOpts
}
type Filter struct {
Field string
Value any
}
func GetList[T any](tx bun.Tx, pageOpts, defaults *PageOpts) *listgetter[T] {
l := &listgetter[T]{
items: new([]*T),
pageOpts: pageOpts,
defaults: defaults,
}
l.q = tx.NewSelect().
Model(l.items)
return l
}
func (l *listgetter[T]) Relation(name string, apply ...func(*bun.SelectQuery) *bun.SelectQuery) *listgetter[T] {
l.q = l.q.Relation(name, apply...)
return l
}
func (l *listgetter[T]) Filter(filters ...Filter) *listgetter[T] {
for _, filter := range filters {
l.q = l.q.Where("? = ?", bun.Ident(filter.Field), filter.Value)
}
return l
}
func (l *listgetter[T]) GetAll(ctx context.Context) (*List[T], error) {
if l.defaults == nil {
return nil, errors.New("default pageopts is nil")
}
total, err := l.q.Count(ctx)
if err != nil {
return nil, errors.Wrap(err, "query.Count")
}
l.q, l.pageOpts = setPageOpts(l.q, l.pageOpts, l.defaults, total)
err = l.q.Scan(ctx)
if err != nil && errors.Is(err, sql.ErrNoRows) {
return nil, errors.Wrap(err, "query.Scan")
}
list := &List[T]{
Items: *l.items,
Total: total,
PageOpts: *l.pageOpts,
}
return list, nil
}