This repository has been archived on 2024-04-06. You can view files and clone it, but cannot push or open issues or pull requests.
core-old/internal/bundb/bundb.go
Dawid Wysokiński def3161957
All checks were successful
continuous-integration/drone/push Build is passing
refactor: scanAndCount - use channel to synchronize data with the main goroutine
2022-12-24 09:10:04 +01:00

106 lines
1.9 KiB
Go

package bundb
import (
"context"
"fmt"
"sync"
"gitea.dwysokinski.me/twhelp/core/internal/domain"
"github.com/uptrace/bun"
)
func appendODSetClauses(q *bun.InsertQuery) *bun.InsertQuery {
return q.Set("rank_att = EXCLUDED.rank_att").
Set("score_att = EXCLUDED.score_att").
Set("rank_def = EXCLUDED.rank_def").
Set("score_def = EXCLUDED.score_def").
Set("rank_sup = EXCLUDED.rank_sup").
Set("score_sup = EXCLUDED.score_sup").
Set("rank_total = EXCLUDED.rank_total").
Set("score_total = EXCLUDED.score_total")
}
type paginationApplier struct {
pagination domain.Pagination
}
func (p paginationApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
if p.pagination.Limit > 0 {
q = q.Limit(int(p.pagination.Limit))
}
if p.pagination.Offset > 0 {
q = q.Offset(int(p.pagination.Offset))
}
return q
}
func sortDirectionToString(sd domain.SortDirection) (string, error) {
switch sd {
case domain.SortDirectionASC:
return "ASC", nil
case domain.SortDirectionDESC:
return "DESC", nil
}
return "", fmt.Errorf("%w: %d", domain.ErrUnsupportedSortDirection, sd)
}
type scanAndCountResult struct {
count int
err error
}
func scanAndCount(
ctx context.Context,
countQ *bun.SelectQuery,
scanQ *bun.SelectQuery,
) (int, error) {
var wg sync.WaitGroup
ch := make(chan scanAndCountResult)
wg.Add(1)
go func() {
defer wg.Done()
count, err := countQ.Count(ctx)
if err != nil {
ch <- scanAndCountResult{err: err}
return
}
ch <- scanAndCountResult{count: count}
}()
wg.Add(1)
go func() {
defer wg.Done()
if err := scanQ.Scan(ctx); err != nil {
ch <- scanAndCountResult{err: err}
}
}()
go func() {
wg.Wait()
close(ch)
}()
var count int
var firstErr error
for res := range ch {
if firstErr == nil && res.err != nil {
firstErr = res.err
continue
}
count = res.count
}
if firstErr != nil {
return 0, firstErr
}
return count, nil
}