mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-05-06 13:19:31 -05:00
Migrate setHistoryByTeamId to Kysely
This commit is contained in:
parent
53d7ca3813
commit
b26f4ab254
|
|
@ -1,8 +1,18 @@
|
|||
import { sql } from "kysely";
|
||||
import { jsonArrayFrom } from "kysely/helpers/sqlite";
|
||||
import { db } from "~/db/sql";
|
||||
import { TournamentMatchStatus } from "~/db/tables";
|
||||
import type { Unwrapped } from "~/utils/types";
|
||||
|
||||
const opponentOneId = sql<number>`"TournamentMatch"."opponentOne" ->> '$.id'`;
|
||||
const opponentTwoId = sql<number>`"TournamentMatch"."opponentTwo" ->> '$.id'`;
|
||||
const opponentOneScore = sql<
|
||||
number | null
|
||||
>`"TournamentMatch"."opponentOne" ->> '$.score'`;
|
||||
const opponentTwoScore = sql<
|
||||
number | null
|
||||
>`"TournamentMatch"."opponentTwo" ->> '$.score'`;
|
||||
|
||||
export type FindMatchById = NonNullable<Unwrapped<typeof findMatchById>>;
|
||||
export async function findMatchById(id: number) {
|
||||
const row = await db
|
||||
|
|
@ -52,12 +62,12 @@ export async function findMatchById(id: number) {
|
|||
innerEb(
|
||||
"TournamentTeamMember.tournamentTeamId",
|
||||
"=",
|
||||
sql<number>`"TournamentMatch"."opponentOne" ->> '$.id'`,
|
||||
opponentOneId,
|
||||
),
|
||||
innerEb(
|
||||
"TournamentTeamMember.tournamentTeamId",
|
||||
"=",
|
||||
sql<number>`"TournamentMatch"."opponentTwo" ->> '$.id'`,
|
||||
opponentTwoId,
|
||||
),
|
||||
]),
|
||||
),
|
||||
|
|
@ -112,3 +122,109 @@ export async function userParticipationByTournamentId(tournamentId: number) {
|
|||
.groupBy("playerMatches.userId")
|
||||
.execute();
|
||||
}
|
||||
|
||||
export type FindByTournamentTeamIdItem = Unwrapped<
|
||||
typeof findByTournamentTeamId
|
||||
>;
|
||||
export function findByTournamentTeamId(tournamentTeamId: number) {
|
||||
return db
|
||||
.selectFrom("TournamentMatch")
|
||||
.innerJoin(
|
||||
"TournamentRound",
|
||||
"TournamentRound.id",
|
||||
"TournamentMatch.roundId",
|
||||
)
|
||||
.innerJoin(
|
||||
"TournamentGroup",
|
||||
"TournamentGroup.id",
|
||||
"TournamentMatch.groupId",
|
||||
)
|
||||
.innerJoin("TournamentTeam as otherTeam", (join) =>
|
||||
join.on((eb) =>
|
||||
eb.or([
|
||||
eb.and([
|
||||
eb(opponentOneId, "!=", tournamentTeamId),
|
||||
eb(opponentOneId, "=", eb.ref("otherTeam.id")),
|
||||
]),
|
||||
eb.and([
|
||||
eb(opponentTwoId, "!=", tournamentTeamId),
|
||||
eb(opponentTwoId, "=", eb.ref("otherTeam.id")),
|
||||
]),
|
||||
]),
|
||||
),
|
||||
)
|
||||
.select(({ eb }) => [
|
||||
"TournamentMatch.id as tournamentMatchId",
|
||||
opponentOneScore.as("opponentOneScore"),
|
||||
opponentTwoScore.as("opponentTwoScore"),
|
||||
"otherTeam.name as otherTeamName",
|
||||
"otherTeam.id as otherTeamId",
|
||||
"TournamentRound.number as roundNumber",
|
||||
"TournamentRound.stageId",
|
||||
"TournamentGroup.number as groupNumber",
|
||||
jsonArrayFrom(
|
||||
eb
|
||||
.selectFrom("TournamentMatchGameResult")
|
||||
.select([
|
||||
"TournamentMatchGameResult.mode",
|
||||
"TournamentMatchGameResult.stageId",
|
||||
"TournamentMatchGameResult.source",
|
||||
sql<number>`"TournamentMatchGameResult"."winnerTeamId" = ${tournamentTeamId}`.as(
|
||||
"wasWinner",
|
||||
),
|
||||
])
|
||||
.whereRef(
|
||||
"TournamentMatchGameResult.matchId",
|
||||
"=",
|
||||
"TournamentMatch.id",
|
||||
)
|
||||
.orderBy("TournamentMatchGameResult.number", "asc"),
|
||||
).as("matches"),
|
||||
jsonArrayFrom(
|
||||
eb
|
||||
.selectFrom("User")
|
||||
.innerJoin(
|
||||
"TournamentMatchGameResultParticipant",
|
||||
"TournamentMatchGameResultParticipant.userId",
|
||||
"User.id",
|
||||
)
|
||||
.innerJoin(
|
||||
"TournamentMatchGameResult",
|
||||
"TournamentMatchGameResult.id",
|
||||
"TournamentMatchGameResultParticipant.matchGameResultId",
|
||||
)
|
||||
.innerJoin("TournamentTeamMember", (join) =>
|
||||
join
|
||||
.onRef("TournamentTeamMember.userId", "=", "User.id")
|
||||
.onRef(
|
||||
"TournamentTeamMember.tournamentTeamId",
|
||||
"=",
|
||||
"otherTeam.id",
|
||||
),
|
||||
)
|
||||
.select([
|
||||
"User.id",
|
||||
"User.username",
|
||||
"User.discordAvatar",
|
||||
"User.discordId",
|
||||
"User.customUrl",
|
||||
])
|
||||
.whereRef(
|
||||
"TournamentMatchGameResult.matchId",
|
||||
"=",
|
||||
"TournamentMatch.id",
|
||||
)
|
||||
.distinct(),
|
||||
).as("players"),
|
||||
])
|
||||
.where((eb) =>
|
||||
eb.or([
|
||||
eb(opponentOneId, "=", tournamentTeamId),
|
||||
eb(opponentTwoId, "=", tournamentTeamId),
|
||||
]),
|
||||
)
|
||||
.where("TournamentMatch.status", ">=", TournamentMatchStatus.Completed)
|
||||
.orderBy("TournamentGroup.number", "asc")
|
||||
.orderBy("TournamentRound.number", "asc")
|
||||
.execute();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
import type { Tables } from "~/db/tables";
|
||||
import type { FindByTournamentTeamIdItem } from "~/features/tournament-bracket/TournamentMatchRepository.server";
|
||||
import type { ModeShort, StageId } from "~/modules/in-game-lists/types";
|
||||
import { sourceTypes } from "~/modules/tournament-map-list-generator/constants";
|
||||
import type { TournamentMaplistSource } from "~/modules/tournament-map-list-generator/types";
|
||||
import invariant from "~/utils/invariant";
|
||||
import { logger } from "~/utils/logger";
|
||||
import { findRoundsByTournamentId } from "../queries/findRoundsByTournamentId.server";
|
||||
import {
|
||||
type SetHistoryByTeamIdItem,
|
||||
setHistoryByTeamId,
|
||||
} from "../queries/setHistoryByTeamId.server";
|
||||
import type { findRoundsByTournamentId } from "../queries/findRoundsByTournamentId.server";
|
||||
|
||||
export interface PlayedSet {
|
||||
tournamentMatchId: number;
|
||||
|
|
@ -78,15 +75,12 @@ export function winCounts(sets: PlayedSet[]) {
|
|||
}
|
||||
|
||||
export function tournamentTeamSets({
|
||||
tournamentTeamId,
|
||||
tournamentId,
|
||||
sets,
|
||||
allRounds,
|
||||
}: {
|
||||
tournamentTeamId: number;
|
||||
tournamentId: number;
|
||||
sets: FindByTournamentTeamIdItem[];
|
||||
allRounds: ReturnType<typeof findRoundsByTournamentId>;
|
||||
}): PlayedSet[] {
|
||||
const sets = setHistoryByTeamId(tournamentTeamId);
|
||||
const allRounds = findRoundsByTournamentId(tournamentId);
|
||||
|
||||
return sets.map((set) => {
|
||||
const round =
|
||||
allRounds.find((round) => round.stageId === set.stageId) ?? allRounds[0];
|
||||
|
|
@ -157,7 +151,7 @@ function parseTournamentMaplistSource(source: string): TournamentMaplistSource {
|
|||
return parsed;
|
||||
}
|
||||
|
||||
function flipScoreIfNeeded(set: SetHistoryByTeamIdItem): [number, number] {
|
||||
function flipScoreIfNeeded(set: FindByTournamentTeamIdItem): [number, number] {
|
||||
const score: [number, number] = [
|
||||
set.opponentOneScore ?? 0,
|
||||
set.opponentTwoScore ?? 0,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { tournamentDataCached } from "~/features/tournament-bracket/core/Tournament.server";
|
||||
import * as TournamentMatchRepository from "~/features/tournament-bracket/TournamentMatchRepository.server";
|
||||
import { tournamentTeamPageParamsSchema } from "~/features/tournament-bracket/tournament-bracket-schemas.server";
|
||||
import { parseParams } from "~/utils/remix.server";
|
||||
import { tournamentTeamSets, winCounts } from "../core/sets.server";
|
||||
import { findRoundsByTournamentId } from "../queries/findRoundsByTournamentId.server";
|
||||
|
||||
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
const { id: tournamentId, tid: tournamentTeamId } = parseParams({
|
||||
|
|
@ -15,7 +17,11 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
|
|||
throw new Response(null, { status: 404 });
|
||||
}
|
||||
|
||||
const sets = tournamentTeamSets({ tournamentTeamId, tournamentId });
|
||||
const setHistory =
|
||||
await TournamentMatchRepository.findByTournamentTeamId(tournamentTeamId);
|
||||
const allRounds = findRoundsByTournamentId(tournamentId);
|
||||
|
||||
const sets = tournamentTeamSets({ sets: setHistory, allRounds });
|
||||
|
||||
return {
|
||||
tournamentTeamId,
|
||||
|
|
|
|||
|
|
@ -1,117 +0,0 @@
|
|||
import * as R from "remeda";
|
||||
import { sql } from "~/db/sql";
|
||||
import type { Tables } from "~/db/tables";
|
||||
import type { ModeShort, StageId } from "~/modules/in-game-lists/types";
|
||||
import { parseDBArray } from "~/utils/sql";
|
||||
|
||||
const stm = sql.prepare(/* sql */ `
|
||||
with "q1" as (
|
||||
select
|
||||
"m"."id" as "tournamentMatchId",
|
||||
"m"."opponentOne" ->> '$.score' as "opponentOneScore",
|
||||
"m"."opponentTwo" ->> '$.score' as "opponentTwoScore",
|
||||
"otherTeam"."name" as "otherTeamName",
|
||||
"otherTeam"."id" as "otherTeamId",
|
||||
"round"."number" as "roundNumber",
|
||||
"round"."stageId" as "stageId",
|
||||
"group"."number" as "groupNumber",
|
||||
json_group_array(
|
||||
json_object(
|
||||
'mode',
|
||||
"r"."mode",
|
||||
'stageId',
|
||||
"r"."stageId",
|
||||
'wasWinner',
|
||||
"r"."winnerTeamId" == @tournamentTeamId,
|
||||
'source',
|
||||
"r"."source"
|
||||
)
|
||||
) as "matches"
|
||||
from "TournamentMatch" as "m"
|
||||
left join "TournamentMatchGameResult" as "r" on "m"."id" = "r"."matchId"
|
||||
left join "TournamentRound" as "round" on "m"."roundId" = "round"."id"
|
||||
left join "TournamentGroup" as "group" on "m"."groupId" = "group"."id"
|
||||
left join "TournamentTeam" as "otherTeam" on
|
||||
(
|
||||
"m"."opponentOne" ->> '$.id' != @tournamentTeamId
|
||||
and
|
||||
"m"."opponentOne" ->> '$.id' = "otherTeam"."id"
|
||||
) or
|
||||
(
|
||||
"m"."opponentTwo" ->> '$.id' != @tournamentTeamId
|
||||
and
|
||||
"m"."opponentTwo" ->> '$.id' = "otherTeam"."id"
|
||||
)
|
||||
where
|
||||
(
|
||||
"m"."opponentOne" ->> '$.id' = @tournamentTeamId
|
||||
or
|
||||
"m"."opponentTwo" ->> '$.id' = @tournamentTeamId
|
||||
)
|
||||
and "m"."status" >= 4
|
||||
group by "m"."id"
|
||||
order by "groupNumber" asc, "roundNumber" asc, "r"."number" asc
|
||||
)
|
||||
select
|
||||
"q1".*,
|
||||
json_group_array(
|
||||
json_object(
|
||||
'id',
|
||||
"u"."id",
|
||||
'username',
|
||||
"u"."username",
|
||||
'discordAvatar',
|
||||
"u"."discordAvatar",
|
||||
'discordId',
|
||||
"u"."discordId",
|
||||
'customUrl',
|
||||
"u"."customUrl"
|
||||
)
|
||||
) as "players"
|
||||
from "q1"
|
||||
left join "TournamentMatchGameResult" as "r" on "q1"."tournamentMatchId" = "r"."matchId"
|
||||
left join "TournamentMatchGameResultParticipant" as "p" on "r"."id" = "p"."matchGameResultId"
|
||||
left join "User" as "u" on "p"."userId" = "u"."id"
|
||||
-- filters out own team results
|
||||
inner join "TournamentTeamMember" as "m" on "p"."userId" = "m"."userId"
|
||||
and "m"."tournamentTeamId" == "q1"."otherTeamId"
|
||||
group by "q1"."tournamentMatchId"
|
||||
`);
|
||||
|
||||
export interface SetHistoryByTeamIdItem {
|
||||
tournamentMatchId: number;
|
||||
opponentOneScore: number | null;
|
||||
opponentTwoScore: number | null;
|
||||
otherTeamName: string;
|
||||
otherTeamId: number;
|
||||
roundNumber: number;
|
||||
stageId: number;
|
||||
groupNumber: number;
|
||||
matches: {
|
||||
stageId: StageId;
|
||||
source: Tables["TournamentMatchGameResult"]["source"];
|
||||
mode: ModeShort;
|
||||
wasWinner: number;
|
||||
}[];
|
||||
players: Array<
|
||||
Pick<
|
||||
Tables["User"],
|
||||
"id" | "username" | "discordAvatar" | "discordId" | "customUrl"
|
||||
>
|
||||
>;
|
||||
}
|
||||
|
||||
export function setHistoryByTeamId(
|
||||
tournamentTeamId: number,
|
||||
): Array<SetHistoryByTeamIdItem> {
|
||||
const rows = stm.all({ tournamentTeamId }) as any[];
|
||||
|
||||
return rows.map((row) => {
|
||||
return {
|
||||
...row,
|
||||
matches: parseDBArray(row.matches),
|
||||
// TODO: there is probably a way to do this in SQL
|
||||
players: R.uniqueBy(parseDBArray(row.players), (u) => u.id),
|
||||
};
|
||||
});
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user