mirror of
https://github.com/djhackersdev/minime.git
synced 2026-08-26 12:41:41 -05:00
idz: Add team "reservation" repository
This is a hack necessary to support certain quirks of the Initial D Zero profile creation process.
This commit is contained in:
@@ -11,6 +11,7 @@ import { SqlStoryRepository } from "./story";
|
||||
import { SqlTeamRepository } from "./team";
|
||||
import { SqlTeamAutoRepository } from "./teamAuto";
|
||||
import { SqlTeamMemberRepository } from "./teamMember";
|
||||
import { SqlTeamReservationRepository } from "./teamReservation";
|
||||
import { SqlTicketsRepository } from "./tickets";
|
||||
import { SqlTimeAttackRepository } from "./timeAttack";
|
||||
import { SqlTitlesRepository } from "./titles";
|
||||
@@ -66,6 +67,10 @@ class TransactionImpl implements Repo.Transaction {
|
||||
return new SqlTeamMemberRepository(this._conn);
|
||||
}
|
||||
|
||||
teamReservations(): Repo.TeamReservationRepository {
|
||||
return new SqlTeamReservationRepository(this._conn);
|
||||
}
|
||||
|
||||
tickets(): Repo.FacetRepository<Model.Tickets> {
|
||||
return new SqlTicketsRepository(this._conn);
|
||||
}
|
||||
|
||||
122
src/idz/db/teamReservation.ts
Normal file
122
src/idz/db/teamReservation.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import * as sql from "sql-bricks-postgres";
|
||||
import { ClientBase } from "pg";
|
||||
|
||||
import { Team } from "../model/team";
|
||||
import { TeamReservationRepository } from "../repo";
|
||||
import { Id } from "../../db";
|
||||
import { AimeId } from "../../model";
|
||||
|
||||
export class SqlTeamReservationRepository
|
||||
implements TeamReservationRepository {
|
||||
constructor(private readonly _conn: ClientBase) {}
|
||||
|
||||
private async _lockTeam(teamId: Id<Team>): Promise<void> {
|
||||
const lockSql = sql
|
||||
.select("t.id")
|
||||
.from("idz.team t")
|
||||
.where("t.id", teamId)
|
||||
.forUpdate()
|
||||
.toParams();
|
||||
|
||||
await this._conn.query(lockSql);
|
||||
}
|
||||
|
||||
async occupancyHack(teamId: Id<Team>): Promise<number> {
|
||||
await this._lockTeam(teamId);
|
||||
|
||||
// counts get returned as strings, so 1 + 0 = 10.
|
||||
// it hardly needs to be said but fuck javascript.
|
||||
|
||||
const memberSql = sql
|
||||
.select("count(*) as count")
|
||||
.from("idz.team_member tm")
|
||||
.where("tm.team_id", teamId)
|
||||
.toParams();
|
||||
|
||||
const memberRes = await this._conn.query(memberSql);
|
||||
const memberCount = parseInt(memberRes.rows[0].count, 10);
|
||||
|
||||
const reservSql = sql
|
||||
.select("count(*) as count")
|
||||
.from("idz.team_reservation tr")
|
||||
.where("tr.team_id", teamId)
|
||||
.toParams();
|
||||
|
||||
const reservRes = await this._conn.query(reservSql);
|
||||
const reservCount = parseInt(reservRes.rows[0].count, 10);
|
||||
|
||||
return memberCount + reservCount;
|
||||
}
|
||||
|
||||
async reserveHack(
|
||||
teamId: Id<Team>,
|
||||
aimeId: AimeId,
|
||||
timestamp: Date,
|
||||
leader?: "leader"
|
||||
): Promise<void> {
|
||||
const lookupSql = sql
|
||||
.select("r.id")
|
||||
.from("aime.player r")
|
||||
.where("r.ext_id", aimeId)
|
||||
.toParams();
|
||||
|
||||
const { rows } = await this._conn.query(lookupSql);
|
||||
const row = rows[0];
|
||||
|
||||
if (row === undefined) {
|
||||
throw new Error(`Unknown Aime ID ${aimeId}`);
|
||||
}
|
||||
|
||||
const playerId = row.id;
|
||||
|
||||
const insertSql = sql
|
||||
.insert("idz.team_reservation", {
|
||||
id: playerId,
|
||||
team_id: teamId,
|
||||
join_time: timestamp,
|
||||
leader: leader === "leader",
|
||||
})
|
||||
.onConflict("id")
|
||||
.doUpdate(["team_id"])
|
||||
.toParams();
|
||||
|
||||
await this._conn.query(insertSql);
|
||||
}
|
||||
|
||||
async commitHack(aimeId: AimeId): Promise<void> {
|
||||
const lookupSql = sql
|
||||
.select("p.id as profile_id", "tr.*")
|
||||
.from("idz.profile p")
|
||||
.join("aime.player r", { "p.player_id": "r.id" })
|
||||
.join("idz.team_reservation tr", { "r.id": "tr.id" })
|
||||
.where("r.ext_id", aimeId)
|
||||
.toParams();
|
||||
|
||||
const { rows } = await this._conn.query(lookupSql);
|
||||
const row = rows[0];
|
||||
|
||||
if (row === undefined) {
|
||||
throw new Error(`Reservation not found for Aime ID ${aimeId}`);
|
||||
}
|
||||
|
||||
console.log(row);
|
||||
|
||||
const insertSql = sql
|
||||
.insert("idz.team_member", {
|
||||
id: row.profile_id,
|
||||
team_id: row.team_id,
|
||||
join_time: row.join_time,
|
||||
leader: row.leader,
|
||||
})
|
||||
.toParams();
|
||||
|
||||
await this._conn.query(insertSql);
|
||||
|
||||
const cleanupSql = sql
|
||||
.delete("idz.team_reservation")
|
||||
.where("id", row.id)
|
||||
.toParams();
|
||||
|
||||
await this._conn.query(cleanupSql);
|
||||
}
|
||||
}
|
||||
@@ -96,6 +96,19 @@ export interface TeamMemberRepository {
|
||||
): Promise<void>;
|
||||
}
|
||||
|
||||
export interface TeamReservationRepository {
|
||||
occupancyHack(teamId: Id<Model.Team>): Promise<number>;
|
||||
|
||||
reserveHack(
|
||||
teamId: Id<Model.Team>,
|
||||
aimeId: AimeId,
|
||||
timestamp: Date,
|
||||
leader?: "leader"
|
||||
): Promise<void>;
|
||||
|
||||
commitHack(aimeId: AimeId): Promise<void>;
|
||||
}
|
||||
|
||||
// TODO extend and factorize
|
||||
export interface TopTenResult {
|
||||
driverName: string;
|
||||
@@ -141,6 +154,8 @@ export interface Repositories {
|
||||
|
||||
teamMembers(): TeamMemberRepository;
|
||||
|
||||
teamReservations(): TeamReservationRepository;
|
||||
|
||||
tickets(): FacetRepository<Model.Tickets>;
|
||||
|
||||
timeAttack(): TimeAttackRepository;
|
||||
|
||||
Reference in New Issue
Block a user