Files
djhackersdev_minime/src/idz/db/car.ts
T

139 lines
3.6 KiB
TypeScript

import sql from "sql-bricks-postgres";
import { Car, CarSelector } from "../model/car";
import { Profile } from "../model/profile";
import { CarRepository } from "../repo";
import { Id } from "../../model";
import { Row, Transaction } from "../../sql";
function _extractRow(row: Row): Car {
return {
selector: parseInt(row.selector) as CarSelector,
field_00: parseInt(row.field_00),
field_02: parseInt(row.field_02),
field_04: row.field_04.split(",").map((x: string) => parseInt(x)),
field_46: parseInt(row.field_46),
field_48: parseInt(row.field_48),
field_4a: parseInt(row.field_4a),
field_4c: parseInt(row.field_4c),
field_50_lo: parseInt(row.field_50_lo),
field_50_hi: parseInt(row.field_50_hi),
field_58: parseInt(row.field_58),
field_5a: parseInt(row.field_5a),
field_5b: parseInt(row.field_5b),
field_5c: parseInt(row.field_5c),
field_5e: parseInt(row.field_5e),
};
}
export class SqlCarRepository implements CarRepository {
constructor(private readonly _txn: Transaction) {}
async countCars(profileId: Id<Profile>): Promise<number> {
const countSql = sql
.select("count(*) result")
.from("idz_car c")
.where("c.profile_id", profileId);
const row = await this._txn.fetchRow(countSql);
return parseInt(row!.result);
}
async loadAllCars(profileId: Id<Profile>): Promise<Car[]> {
const loadSql = sql
.select("c.*")
.from("idz_car c")
.where("c.profile_id", profileId);
const rows = await this._txn.fetchRows(loadSql);
return rows.map(_extractRow);
}
async loadSelectedCar(profileId: Id<Profile>): Promise<Car> {
const loadSql = sql
.select("c.*")
.from("idz_car c")
.join("idz_car_selection s", { "c.id": "s.car_id" })
.where("s.id", profileId);
const row = await this._txn.fetchRow(loadSql);
if (row === undefined) {
throw new Error(`Car selection not found, profileId=${profileId}`);
}
return _extractRow(row);
}
async saveCar(profileId: Id<Profile>, car: Car): Promise<void> {
const saveSql = sql
.insert("idz_car", {
id: this._txn.generateId(),
profile_id: profileId,
selector: car.selector,
field_00: car.field_00,
field_02: car.field_02,
field_04: car.field_04.join(","),
field_46: car.field_46,
field_48: car.field_48,
field_4a: car.field_4a,
field_4c: car.field_4c,
field_50_lo: car.field_50_lo,
field_50_hi: car.field_50_hi,
field_58: car.field_58,
field_5a: car.field_5a,
field_5b: car.field_5b,
field_5c: car.field_5c,
field_5e: car.field_5e,
})
.onConflict("profile_id", "selector")
.doUpdate([
"field_00",
"field_02",
"field_04",
"field_46",
"field_48",
"field_4a",
"field_4c",
"field_50_lo",
"field_50_hi",
"field_58",
"field_5a",
"field_5b",
"field_5c",
"field_5e",
]);
await this._txn.modify(saveSql);
}
async saveSelection(
profileId: Id<Profile>,
selector: CarSelector
): Promise<void> {
const findSql = sql
.select("c.id")
.from("idz_car c")
.where("c.profile_id", profileId)
.where("c.selector", selector);
const row = await this._txn.fetchRow(findSql);
if (row === undefined) {
throw new Error("Selected car not found");
}
const saveSql = sql
.insert("idz_car_selection", {
id: profileId,
car_id: row.id,
})
.onConflict("id")
.doUpdate(["car_id"]);
await this._txn.modify(saveSql);
}
}