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/tribe_change.go
Dawid Wysokiński bf29ab4799
All checks were successful
continuous-integration/drone/push Build is passing
feat: new rest endpoint - /versions/{code}/servers/{key}/tribes/{id}/tribe-changes (#181)
Reviewed-on: twhelp/core#181
2023-02-10 05:56:39 +00:00

174 lines
4.5 KiB
Go

package bundb
import (
"context"
"database/sql"
"errors"
"fmt"
"gitea.dwysokinski.me/twhelp/core/internal/bundb/internal/model"
"gitea.dwysokinski.me/twhelp/core/internal/domain"
"github.com/uptrace/bun"
)
var (
tribeChangeOrders = []string{"tc.server_key ASC"}
)
type TribeChange struct {
db *bun.DB
}
func NewTribeChange(db *bun.DB) *TribeChange {
return &TribeChange{db: db}
}
func (t *TribeChange) Create(ctx context.Context, params ...domain.CreateTribeChangeParams) error {
if len(params) == 0 {
return nil
}
tcs := make([]model.TribeChange, 0, len(params))
for _, param := range params {
tcs = append(tcs, model.NewTribeChange(param))
}
if _, err := t.db.NewInsert().
Model(&tcs).
Returning("NULL").
Exec(ctx); err != nil {
return fmt.Errorf("something went wrong while inserting tribe changes into the db: %w", err)
}
return nil
}
func (t *TribeChange) List(ctx context.Context, params domain.ListTribeChangesParams) ([]domain.TribeChange, error) {
var tcs []model.TribeChange
if err := t.db.NewSelect().
Model(&tcs).
Order(tribeChangeOrders...).
Apply(listTribeChangesParamsApplier{params}.apply).
Scan(ctx); err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, fmt.Errorf("couldn't select tribe changes from the db: %w", err)
}
result := make([]domain.TribeChange, 0, len(tcs))
for _, tc := range tcs {
result = append(result, tc.ToDomain())
}
return result, nil
}
func (t *TribeChange) ListCountWithRelations(
ctx context.Context,
params domain.ListTribeChangesParams,
) ([]domain.TribeChangeWithRelations, int64, error) {
var tcs []model.TribeChange
paramsApplier := listTribeChangesParamsApplier{params}
subQ := t.db.NewSelect().
Column("id").
Model(&model.TribeChange{}).
Order(tribeChangeOrders...).
Apply(paramsApplier.apply)
cntQ := t.db.NewSelect().
Model(&model.TribeChange{}).
Apply(paramsApplier.applyFilters)
q := t.db.NewSelect().
Model(&tcs).
Order(tribeChangeOrders...).
Apply(paramsApplier.applySort).
Where("tc.id IN (?)", subQ).
Relation("Player", func(q *bun.SelectQuery) *bun.SelectQuery {
return q.Column(playerMetaColumns...)
}).
Relation("NewTribe", func(q *bun.SelectQuery) *bun.SelectQuery {
return q.Column(tribeMetaColumns...)
}).
Relation("OldTribe", func(q *bun.SelectQuery) *bun.SelectQuery {
return q.Column(tribeMetaColumns...)
})
count, err := scanAndCount(ctx, cntQ, q)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, 0, fmt.Errorf("couldn't select tribe changes from the db: %w", err)
}
result := make([]domain.TribeChangeWithRelations, 0, len(tcs))
for _, tc := range tcs {
result = append(result, tc.ToDomainWithRelations())
}
return result, int64(count), nil
}
type listTribeChangesParamsApplier struct {
params domain.ListTribeChangesParams
}
func (l listTribeChangesParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
return q.Apply(l.applySort).Apply(l.applyFilters).Apply(l.applyPagination)
}
func (l listTribeChangesParamsApplier) applyFilters(q *bun.SelectQuery) *bun.SelectQuery {
if len(l.params.ServerKeys) > 0 {
q = q.Where("tc.server_key IN (?)", bun.In(l.params.ServerKeys))
}
if len(l.params.PlayerIDs) > 0 {
q = q.Where("tc.player_id IN (?)", bun.In(l.params.PlayerIDs))
}
if len(l.params.TribeIDs) > 0 {
q = q.WhereGroup(" AND ", func(q *bun.SelectQuery) *bun.SelectQuery {
return q.WhereOr("tc.new_tribe_id IN (?)", bun.In(l.params.TribeIDs)).
WhereOr("tc.old_tribe_id IN (?)", bun.In(l.params.TribeIDs))
})
}
return q
}
func (l listTribeChangesParamsApplier) applySort(q *bun.SelectQuery) *bun.SelectQuery {
if len(l.params.Sort) == 0 {
return q
}
orders := make([]string, 0, len(l.params.Sort))
for i, s := range l.params.Sort {
column, err := tribeChangeSortByToColumn(s.By)
if err != nil {
return q.Err(fmt.Errorf("tribeChangeSortByToColumn (index=%d): %w", i, err))
}
direction, err := sortDirectionToString(s.Direction)
if err != nil {
return q.Err(fmt.Errorf("sortDirectionToString (index=%d): %w", i, err))
}
orders = append(orders, column+" "+direction)
}
return q.Order(orders...)
}
func (l listTribeChangesParamsApplier) applyPagination(q *bun.SelectQuery) *bun.SelectQuery {
return (paginationApplier{pagination: l.params.Pagination}).apply(q)
}
func tribeChangeSortByToColumn(sortBy domain.TribeChangeSortBy) (string, error) {
switch sortBy {
case domain.TribeChangeSortByID:
return "tc.id", nil
case domain.TribeChangeSortByCreatedAt:
return "tc.created_at", nil
}
return "", fmt.Errorf("%w: %d", domain.ErrUnsupportedSortBy, sortBy)
}