diff --git a/src/idz/db/missions.ts b/src/idz/db/missions.ts new file mode 100644 index 0000000..3d628b1 --- /dev/null +++ b/src/idz/db/missions.ts @@ -0,0 +1,83 @@ +import { Client } from "pg"; +import * as sql from "sql-bricks-postgres"; + +import { _findProfile } from "./_util"; +import { ExtId } from "../model/base"; +import { MissionGrid, MissionState } from "../model/mission"; +import { Profile } from "../model/profile"; +import { FacetRepository } from "../repo"; +import { generateId, Id } from "../../db"; + +export class SqlMissionsRepository implements FacetRepository { + constructor(private readonly _conn: Client) {} + + private async _load( + extId: ExtId + ): Promise<[MissionState, Id]> { + const result: MissionState = { + team: new Array(), + solo: new Array(), + }; + + for (let i = 0; i < 5; i++) { + const soloGrid: MissionGrid = { cells: new Array() }; + const teamGrid: MissionGrid = { cells: new Array() }; + + for (let j = 0; j < 9; j++) { + soloGrid.cells.push(0); + teamGrid.cells.push(0); + } + } + + const profileId = await _findProfile(this._conn, extId); + + const loadSoloSql = sql + .select("sm.*") + .from("idz.solo_mission_state sm") + .where("sm.profile_id", profileId) + .toParams(); + + const { rows } = await this._conn.query(loadSoloSql); + + for (const row of rows) { + result.solo[row.grid_no].cells[row.cell_no] = row.value; + } + + return [result, profileId]; + } + + async load(extId: ExtId): Promise { + const [mission] = await this._load(extId); + + return mission; + } + + async save(extId: ExtId, mission: MissionState): Promise { + const [existing, profileId] = await this._load(extId); + + for (let i = 0; i < mission.solo.length; i++) { + const exGrid = existing.solo[i].cells; + const grid = mission.solo[i].cells; + + for (let j = 0; j < grid.length; j++) { + if (grid[j] === exGrid[j]) { + continue; // Most if not all cells are unaffected on save + } + + const saveSql = sql + .insert("idz.mission_state", { + id: generateId(), + profile_id: profileId, + grid_no: i, + cell_no: j, + value: grid[j], + }) + .onConflict("profile_id", "grid_no", "cell_no") + .doUpdate("value") + .toParams(); + + await this._conn.query(saveSql); + } + } + } +} diff --git a/src/idz/decoder/_mission.ts b/src/idz/decoder/_mission.ts index 3470bf5..038b01d 100644 --- a/src/idz/decoder/_mission.ts +++ b/src/idz/decoder/_mission.ts @@ -4,7 +4,7 @@ export function mission(buf: Buffer): MissionGrid[] { const grids = new Array(); for (let gridNo = 0; gridNo < 5; gridNo++) { - const grid: MissionGrid = { gridNo, cells: [] }; + const grid: MissionGrid = { cells: [] }; for (let cellNo = 0; cellNo < 9; cellNo++) { let cell = 0; diff --git a/src/idz/encoder/_mission.ts b/src/idz/encoder/_mission.ts index 5c64a97..b9fbd0f 100644 --- a/src/idz/encoder/_mission.ts +++ b/src/idz/encoder/_mission.ts @@ -3,8 +3,8 @@ import { MissionGrid } from "../model/mission"; export function mission(grids: MissionGrid[]): Buffer { const buf = Buffer.alloc(0x24); - for (const grid of grids) { - const { gridNo } = grid; + for (let gridNo = 0; gridNo < grids.length; gridNo++) { + const grid = grids[gridNo]; const slices = [0, 0, 0]; for (let cellNo = 0; cellNo < 9 && cellNo < grid.cells.length; cellNo++) { diff --git a/src/idz/model/mission.ts b/src/idz/model/mission.ts index 61f5fe6..f981ceb 100644 --- a/src/idz/model/mission.ts +++ b/src/idz/model/mission.ts @@ -1,5 +1,4 @@ export interface MissionGrid { - gridNo: number; cells: number[]; }