idz: Add SqlProfileRepository

This commit is contained in:
Tau
2019-04-28 22:16:24 -04:00
parent d502ed5d61
commit 5bf90b899a
4 changed files with 162 additions and 44 deletions

117
src/idz/db/profile.ts Normal file
View File

@@ -0,0 +1,117 @@
import * as sql from "sql-bricks";
import { Client } from "pg";
import { _findProfile } from "./_util";
import { ExtId } from "../model/base";
import { Profile } from "../model/profile";
import { Team } from "../model/team";
import { ProfileSpec, ProfileRepository } from "../repo";
import { generateExtId, generateId, Id } from "../../db";
import { AimeId } from "../../model";
function _extractRow(row: any): Profile {
return {
id: row.ext_id,
teamId: 2 as ExtId<Team>, // TODO
name: row.name,
lv: row.lv,
exp: row.exp,
fame: row.fame,
dpoint: row.dpoint,
mileage: row.mileage,
};
}
export class SqlProfileRepository implements ProfileRepository {
constructor(private readonly _conn: Client) {}
async discoverByAimeId(aimeId: AimeId): Promise<boolean> {
const profileId = await this._findProfile(aimeId);
return profileId !== undefined;
}
async loadByAimeId(aimeId: AimeId): Promise<Profile> {
const profileId = await this._findProfile(aimeId);
if (profileId === undefined) {
throw new Error("Profile not found");
}
const loadSql = sql
.select()
.from("idz.profile")
.where("id", profileId)
.toParams();
const { rows } = await this._conn.query(loadSql);
return _extractRow(rows[0]);
}
async load(extId: ExtId<Profile>): Promise<Profile> {
const loadSql = sql
.select()
.from("idz.profile")
.where("ext_id", extId)
.toParams();
const { rows } = await this._conn.query(loadSql);
return _extractRow(rows[0]);
}
async save(profile: Profile): Promise<void> {
const saveSql = sql
.update("idz.profile", {
lv: profile.lv,
exp: profile.exp,
fame: profile.fame,
dpoint: profile.dpoint,
mileage: profile.mileage,
})
.where("ext_id", profile.id)
.toParams();
await this._conn.query(saveSql);
}
async create(profile: ProfileSpec): Promise<ExtId<Profile>> {
const id = generateId();
const extId = generateExtId() as ExtId<Profile>;
const createSql = sql
.insert("idz.profile", {
id: id,
ext_id: extId,
name: profile.name,
lv: profile.lv,
exp: profile.exp,
fame: profile.fame,
dpoint: profile.dpoint,
mileage: profile.mileage,
})
.toParams();
await this._conn.query(createSql);
return extId;
}
async _findProfile(aimeId: AimeId): Promise<Id<Profile> | undefined> {
const lookupSql = sql
.select("r.id")
.from("idz.profile r")
.join("aime.player p", { "r.player_id": "p.id" })
.where("p.aime_id", aimeId)
.toParams();
const { rows } = await this._conn.query(lookupSql);
if (rows.length > 0) {
return rows[0].id as Id<Profile>;
} else {
return undefined;
}
}
}

View File

@@ -1,22 +1,18 @@
import { ExtId } from "../model/base";
import { MissionState } from "../model/mission";
import { Profile } from "../model/profile";
import { Settings } from "../model/settings";
import { Story } from "../model/story";
import { Team } from "../model/team";
import { Unlocks } from "../model/unlocks";
import { CreateProfileRequest } from "../request/createProfile";
import { GenericResponse } from "../response/generic";
import { Repositories } from "../repo";
import { ProfileSpec, Repositories } from "../repo";
export async function createProfile(
w: Repositories,
req: CreateProfileRequest
): Promise<GenericResponse> {
const profileId = await w.profile().generateId();
const profile: Profile = {
id: profileId,
const profile: ProfileSpec = {
teamId: 2 as ExtId<Team>, // TODO
name: req.name,
lv: 1,
@@ -36,17 +32,16 @@ export async function createProfile(
lastMileageReward: 0,
};
await Promise.all([
w.profile().save(profile.id, profile),
w.chara().save(profile.id, req.chara),
w.car().saveCar(profile.id, req.car),
w.car().saveSelection(profile.id, req.car.selector),
w.missions().save(profile.id, missions),
w.settings().save(profile.id, settings),
w.story().save(profile.id, story),
w.unlocks().save(profile.id, unlocks),
w.tickets().save(profile.id, {}),
]);
const profileId = await w.profile().create(profile);
await w.chara().save(profileId, req.chara);
await w.car().saveCar(profileId, req.car);
await w.car().saveSelection(profileId, req.car.selector);
await w.missions().save(profileId, missions);
await w.settings().save(profileId, settings);
await w.story().save(profileId, story);
await w.unlocks().save(profileId, unlocks);
await w.tickets().save(profileId, {});
return {
type: "generic_res",

View File

@@ -9,29 +9,29 @@ export async function saveProfile(
const profile = await w.profile().load(req.profileId);
const chara = await w.chara().load(req.profileId);
await Promise.all([
w.profile().save(req.profileId, {
...profile,
lv: req.lv,
exp: req.exp,
fame: req.fame,
dpoint: req.dpoint,
mileage: req.mileage,
}),
w.chara().save(req.profileId, {
...chara,
title: req.title,
background: req.background,
}),
w.car().saveCar(req.profileId, req.car),
w.coursePlays().saveAll(req.profileId, req.coursePlays),
w.missions().save(req.profileId, req.missions),
w.story().save(req.profileId, req.story),
w.titles().saveAll(req.profileId, req.titles),
w.unlocks().save(req.profileId, req.unlocks),
w.settings().save(req.profileId, req.settings),
w.tickets().save(req.profileId, req.tickets),
]);
await w.profile().save({
...profile,
lv: req.lv,
exp: req.exp,
fame: req.fame,
dpoint: req.dpoint,
mileage: req.mileage,
});
await w.chara().save(req.profileId, {
...chara,
title: req.title,
background: req.background,
});
await w.car().saveCar(req.profileId, req.car);
await w.coursePlays().saveAll(req.profileId, req.coursePlays);
await w.missions().save(req.profileId, req.missions);
await w.story().save(req.profileId, req.story);
await w.titles().saveAll(req.profileId, req.titles);
await w.unlocks().save(req.profileId, req.unlocks);
await w.settings().save(req.profileId, req.settings);
await w.tickets().save(req.profileId, req.tickets);
return {
type: "generic_res",

View File

@@ -1,6 +1,13 @@
import { Subtract } from "utility-types";
import * as Model from "./model";
import { AimeId } from "../model";
export type ProfileSpec = Subtract<
Model.Profile,
{ id: Model.ExtId<Model.Profile> }
>;
export interface CarRepository {
countCars(profileId: Model.ExtId<Model.Profile>): Promise<number>;
@@ -41,16 +48,15 @@ export interface FlagRepository<T extends number> {
}
export interface ProfileRepository {
// Might want to come up with something better here
generateId(): Promise<Model.ExtId<Model.Profile>>;
discoverByAimeId(id: AimeId): Promise<boolean>;
loadByAimeId(id: AimeId): Promise<Model.Profile>;
load(id: Model.ExtId<Model.Profile>): Promise<Model.Profile>;
save(id: Model.ExtId<Model.Profile>, profile: Model.Profile): Promise<void>;
save(profile: Model.Profile): Promise<void>;
create(profile: ProfileSpec): Promise<Model.ExtId<Model.Profile>>;
}
export interface TimeAttackRepository {