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/ennoblement.go
Dawid Wysokiński badb7276fb
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
refactor: check if len() > 0 instead of != nil for slices
2023-02-08 07:04:22 +01:00

208 lines
5.7 KiB
Go

package bundb
import (
"context"
"database/sql"
"errors"
"fmt"
"time"
"gitea.dwysokinski.me/twhelp/core/internal/bundb/internal/model"
"gitea.dwysokinski.me/twhelp/core/internal/domain"
"github.com/uptrace/bun"
)
var (
ennoblementOrders = []string{"ennoblement.server_key ASC"}
)
type Ennoblement struct {
db *bun.DB
}
func NewEnnoblement(db *bun.DB) *Ennoblement {
return &Ennoblement{db: db}
}
func (e *Ennoblement) Create(ctx context.Context, params ...domain.CreateEnnoblementParams) error {
if len(params) == 0 {
return nil
}
ennoblements := make([]model.Ennoblement, 0, len(params))
for _, p := range params {
ennoblements = append(ennoblements, model.NewEnnoblement(p))
}
if _, err := e.db.NewInsert().
Model(&ennoblements).
Returning("NULL").
Ignore().
Exec(ctx); err != nil {
return fmt.Errorf("something went wrong while inserting ennoblements into the db: %w", err)
}
return nil
}
func (e *Ennoblement) List(ctx context.Context, params domain.ListEnnoblementsParams) ([]domain.Ennoblement, error) {
var ennoblements []model.Ennoblement
if err := e.db.NewSelect().
Model(&ennoblements).
Order(ennoblementOrders...).
Apply(listEnnoblementsParamsApplier{params}.apply).
Scan(ctx); err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, fmt.Errorf("couldn't select ennoblements from the db: %w", err)
}
result := make([]domain.Ennoblement, 0, len(ennoblements))
for _, ennoblement := range ennoblements {
result = append(result, ennoblement.ToDomain())
}
return result, nil
}
func (e *Ennoblement) ListCountWithRelations(
ctx context.Context,
params domain.ListEnnoblementsParams,
) ([]domain.EnnoblementWithRelations, int64, error) {
var ennoblements []model.Ennoblement
paramsApplier := listEnnoblementsParamsApplier{params}
cntQ := e.db.NewSelect().
Model(&model.Ennoblement{}).
Apply(paramsApplier.applyFilters)
subQ := e.db.NewSelect().
Column("id").
Model(&model.Ennoblement{}).
Order(ennoblementOrders...).
Apply(paramsApplier.apply)
q := e.db.NewSelect().
Model(&ennoblements).
Where("ennoblement.id IN (?)", subQ).
Order(ennoblementOrders...).
Apply(paramsApplier.applySort).
Relation("OldOwner", func(q *bun.SelectQuery) *bun.SelectQuery {
return q.Column(playerMetaColumns...)
}).
Relation("OldTribe", func(q *bun.SelectQuery) *bun.SelectQuery {
return q.Column(tribeMetaColumns...)
}).
Relation("NewOwner", func(q *bun.SelectQuery) *bun.SelectQuery {
return q.Column(playerMetaColumns...)
}).
Relation("NewTribe", func(q *bun.SelectQuery) *bun.SelectQuery {
return q.Column(tribeMetaColumns...)
}).
Relation("Village", func(q *bun.SelectQuery) *bun.SelectQuery {
return q.Column(villageMetaColumns...)
})
count, err := scanAndCount(ctx, cntQ, q)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, 0, fmt.Errorf("couldn't select ennoblements from the db: %w", err)
}
result := make([]domain.EnnoblementWithRelations, 0, len(ennoblements))
for _, ennoblement := range ennoblements {
result = append(result, ennoblement.ToDomainWithRelations())
}
return result, int64(count), nil
}
func (e *Ennoblement) Delete(ctx context.Context, serverKey string, createdAtLTE time.Time) error {
if _, err := e.db.NewDelete().
Model(&model.Ennoblement{}).
Where("server_key = ?", serverKey).
Where("created_at <= ?", createdAtLTE).
Returning("NULL").
Exec(ctx); err != nil {
return fmt.Errorf("couldn't delete ennoblements: %w", err)
}
return nil
}
type listEnnoblementsParamsApplier struct {
params domain.ListEnnoblementsParams
}
func (l listEnnoblementsParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
return q.Apply(l.applySort).Apply(l.applyFilters).Apply(l.applyPagination)
}
func (l listEnnoblementsParamsApplier) applyFilters(q *bun.SelectQuery) *bun.SelectQuery {
if len(l.params.ServerKeys) > 0 {
q = q.Where("ennoblement.server_key IN (?)", bun.In(l.params.ServerKeys))
}
if l.params.CreatedAtGTE.Valid {
q = q.Where("ennoblement.created_at >= ?", l.params.CreatedAtGTE.Time)
}
if l.params.CreatedAtLTE.Valid {
q = q.Where("ennoblement.created_at <= ?", l.params.CreatedAtLTE.Time)
}
if l.params.PlayerID > 0 {
q = q.WhereGroup(" AND ", func(q *bun.SelectQuery) *bun.SelectQuery {
return q.WhereOr("ennoblement.new_owner_id = ?", l.params.PlayerID).
WhereOr("ennoblement.old_owner_id = ?", l.params.PlayerID)
})
}
if l.params.TribeID > 0 {
q = q.WhereGroup(" AND ", func(q *bun.SelectQuery) *bun.SelectQuery {
return q.WhereOr("ennoblement.new_tribe_id = ?", l.params.TribeID).
WhereOr("ennoblement.old_tribe_id = ?", l.params.TribeID)
})
}
if l.params.VillageID > 0 {
q = q.Where("village_id = ?", l.params.VillageID)
}
return q
}
func (l listEnnoblementsParamsApplier) 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 := ennoblementSortByToColumn(s.By)
if err != nil {
return q.Err(fmt.Errorf("ennoblementSortByToColumn (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 listEnnoblementsParamsApplier) applyPagination(q *bun.SelectQuery) *bun.SelectQuery {
return (paginationApplier{pagination: l.params.Pagination}).apply(q)
}
func ennoblementSortByToColumn(sortBy domain.EnnoblementSortBy) (string, error) {
switch sortBy {
case domain.EnnoblementSortByCreatedAt:
return "ennoblement.created_at", nil
default:
return "", fmt.Errorf("%w: %d", domain.ErrUnsupportedSortBy, sortBy)
}
}