151 lines
4.3 KiB
Go
151 lines
4.3 KiB
Go
package adapter
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"gitea.dwysokinski.me/twhelp/core/internal/adapter/internal/bunmodel"
|
|
"gitea.dwysokinski.me/twhelp/core/internal/domain"
|
|
"github.com/uptrace/bun"
|
|
)
|
|
|
|
type TribeSnapshotBunRepository struct {
|
|
db *bun.DB
|
|
}
|
|
|
|
func NewTribeSnapshotBunRepository(db *bun.DB) *TribeSnapshotBunRepository {
|
|
return &TribeSnapshotBunRepository{db: db}
|
|
}
|
|
|
|
func (t *TribeSnapshotBunRepository) Create(ctx context.Context, params ...domain.CreateTribeSnapshotParams) error {
|
|
if len(params) == 0 {
|
|
return nil
|
|
}
|
|
|
|
snapshots := make([]bunmodel.TribeSnapshot, 0, len(params))
|
|
for _, param := range params {
|
|
snapshots = append(snapshots, bunmodel.NewTribeSnapshot(param))
|
|
}
|
|
|
|
if _, err := t.db.NewInsert().
|
|
Model(&snapshots).
|
|
Returning("NULL").
|
|
Exec(ctx); err != nil {
|
|
return fmt.Errorf("something went wrong while inserting tribe snapshots into the db: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (t *TribeSnapshotBunRepository) List(ctx context.Context, params domain.ListTribeSnapshotsParams) ([]domain.TribeSnapshot, error) {
|
|
var snapshots []bunmodel.TribeSnapshot
|
|
|
|
if err := t.buildListQuery(&snapshots, params).Scan(ctx); err != nil && !errors.Is(err, sql.ErrNoRows) {
|
|
return nil, fmt.Errorf("couldn't select tribe snapshots from the db: %w", err)
|
|
}
|
|
|
|
result := make([]domain.TribeSnapshot, 0, len(snapshots))
|
|
for _, snapshot := range snapshots {
|
|
result = append(result, snapshot.ToDomain())
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func (t *TribeSnapshotBunRepository) ListCount(ctx context.Context, params domain.ListTribeSnapshotsParams) ([]domain.TribeSnapshot, int64, error) {
|
|
var snapshots []bunmodel.TribeSnapshot
|
|
|
|
q := t.buildListQuery(&snapshots, params)
|
|
count, err := scanAndCount(ctx, q, q)
|
|
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
|
return nil, 0, fmt.Errorf("couldn't select tribe snapshots from the db: %w", err)
|
|
}
|
|
|
|
result := make([]domain.TribeSnapshot, 0, len(snapshots))
|
|
for _, snapshot := range snapshots {
|
|
result = append(result, snapshot.ToDomain())
|
|
}
|
|
|
|
return result, int64(count), nil
|
|
}
|
|
|
|
func (t *TribeSnapshotBunRepository) buildListQuery(snapshots *[]bunmodel.TribeSnapshot, params domain.ListTribeSnapshotsParams) *bun.SelectQuery {
|
|
return t.db.NewSelect().
|
|
Model(snapshots).
|
|
Order("ts.server_key ASC").
|
|
Apply(listTribeSnapshotsParamsApplier{params}.apply)
|
|
}
|
|
|
|
func (t *TribeSnapshotBunRepository) Delete(ctx context.Context, serverKey string, createdAtLTE time.Time) error {
|
|
if _, err := t.db.NewDelete().
|
|
Model(&bunmodel.TribeSnapshot{}).
|
|
Where("server_key = ?", serverKey).
|
|
Where("created_at <= ?", createdAtLTE).
|
|
Returning("NULL").
|
|
Exec(ctx); err != nil {
|
|
return fmt.Errorf("couldn't delete tribe snapshots: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type listTribeSnapshotsParamsApplier struct {
|
|
params domain.ListTribeSnapshotsParams
|
|
}
|
|
|
|
func (l listTribeSnapshotsParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
|
|
return q.Apply(l.applyPagination).Apply(l.applySort).Apply(l.applyFilters)
|
|
}
|
|
|
|
func (l listTribeSnapshotsParamsApplier) applyFilters(q *bun.SelectQuery) *bun.SelectQuery {
|
|
if len(l.params.ServerKeys) > 0 {
|
|
q = q.Where("ts.server_key IN (?)", bun.In(l.params.ServerKeys))
|
|
}
|
|
|
|
if len(l.params.TribeIDs) > 0 {
|
|
q = q.Where("ts.tribe_id IN (?)", bun.In(l.params.TribeIDs))
|
|
}
|
|
|
|
return q
|
|
}
|
|
|
|
func (l listTribeSnapshotsParamsApplier) 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 := tribeSnapshotSortByToColumn(s.By)
|
|
if err != nil {
|
|
return q.Err(fmt.Errorf("tribeSnapshotSortByToColumn (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 listTribeSnapshotsParamsApplier) applyPagination(q *bun.SelectQuery) *bun.SelectQuery {
|
|
return (paginationApplier{pagination: l.params.Pagination}).apply(q)
|
|
}
|
|
|
|
func tribeSnapshotSortByToColumn(sortBy domain.TribeSnapshotSortBy) (string, error) {
|
|
switch sortBy {
|
|
case domain.TribeSnapshotSortByID:
|
|
return "ts.id", nil
|
|
case domain.TribeSnapshotSortByDate:
|
|
return "ts.date", nil
|
|
}
|
|
return "", fmt.Errorf("%w: %d", domain.ErrUnsupportedSortBy, sortBy)
|
|
}
|