idz: Add stamps tables

This commit is contained in:
BemaniWitch
2020-10-25 20:38:35 -04:00
committed by Tau
parent 48a9bcbdbd
commit c2fbb0ddff
12 changed files with 196 additions and 3 deletions

View File

@@ -108,6 +108,25 @@ create table "idz_settings" (
"driving_style" integer not null
);
create table "idz_stamp_selections" (
"id" integer primary key not null
references "idz_profile"("id")
on delete cascade,
"stamp_01" integer not null,
"stamp_02" integer not null,
"stamp_03" integer not null,
"stamp_04" integer not null
);
create table "idz_stamp_unlock" (
"id" integer primary key not null,
"profile_id" integer not null
references "idz_profile"("id")
on delete cascade,
"stamp_no",
constraint "idz_stamp_unlock_uq" unique ("profile_id", "stamp_no")
);
create table "idz_story_state" (
"id" integer primary key not null
references "idz_profile"("id")

View File

@@ -10,6 +10,25 @@ create table "new_idz_settings" (
"driving_style" integer not null
);
create table "idz_stamp_selections" (
"id" integer primary key not null
references "idz_profile"("id")
on delete cascade,
"stamp_01" integer not null,
"stamp_02" integer not null,
"stamp_03" integer not null,
"stamp_04" integer not null
);
create table "idz_stamp_unlock" (
"id" integer primary key not null,
"profile_id" integer not null
references "idz_profile"("id")
on delete cascade,
"stamp_no",
constraint "idz_stamp_unlock_uq" unique ("profile_id", "stamp_no")
);
insert into "new_idz_settings" (
"id",
"music",

View File

@@ -28,6 +28,8 @@ export async function loadProfile(
const unlocks = await w.unlocks().load(profileId);
const tickets = await w.tickets().load(profileId);
const team = teamId && (await w.teams().load(teamId));
const stamps = await w.stamps().loadAll(profileId);
const selectedStamps = await w.stamps().loadSelection(profileId);
return {
type: "load_profile_res",
@@ -51,5 +53,7 @@ export async function loadProfile(
story,
unlocks,
tickets,
stamps,
selectedStamps,
};
}

View File

@@ -36,6 +36,14 @@ export async function saveProfile(
await w.settings().save(profileId, req.settings);
await w.tickets().save(profileId, req.tickets);
if (req.selectedStamps) {
await w.stamps().saveSelection(profileId, req.selectedStamps);
}
if (req.stamps) {
await w.stamps().saveAll(profileId, req.stamps);
}
return {
type: "generic_res",
status: 1,

View File

@@ -5,4 +5,5 @@ export type BackgroundCode = number & { __brand: "backgroundCode" };
export type CourseNo = number & { __brand: "courseNo" };
export type ExtId<T> = number & { __extId: T };
export type RouteNo = number & { __brand: "routeNo" };
export type StampCode = number & { __brand: "stampCode" };
export type TitleCode = number & { __brand: "titleCode" };

View File

@@ -1,9 +1,17 @@
export { BackgroundCode, CourseNo, ExtId, RouteNo, TitleCode } from "./base";
export {
BackgroundCode,
CourseNo,
ExtId,
RouteNo,
StampCode,
TitleCode,
} from "./base";
export { Car, CarSelector } from "./car";
export { Chara } from "./chara";
export { MissionState, MissionGrid } from "./mission";
export { Profile } from "./profile";
export { Settings } from "./settings";
export { SelectedStamps } from "./stamps";
export { Story } from "./story";
export { Team, TeamAuto, TeamMember } from "./team";
export { Tickets } from "./tickets";

View File

@@ -0,0 +1,8 @@
import { StampCode } from "./base";
export interface SelectedStamps {
stamp01: StampCode;
stamp02: StampCode;
stamp03: StampCode;
stamp04: StampCode;
}

View File

@@ -63,6 +63,22 @@ export interface ProfileRepository {
create(profile: Model.Profile): Promise<Id<Model.Profile>>;
}
export interface StampsRepository {
loadSelection(profileId: Id<Model.Profile>): Promise<Model.SelectedStamps>;
loadAll(profileId: Id<Model.Profile>): Promise<Set<Model.StampCode>>;
saveAll(
profileId: Id<Model.Profile>,
items: Set<Model.StampCode>
): Promise<void>;
saveSelection(
profileId: Id<Model.Profile>,
selection: Model.SelectedStamps
): Promise<void>;
}
export interface TeamRepository {
find(
extId: Model.ExtId<Model.Team>,
@@ -156,6 +172,8 @@ export interface Repositories {
settings(): FacetRepository<Model.Settings>;
stamps(): StampsRepository;
// Also not a facet. w/e one step at a time.
story(): FacetRepository<Model.Story>;

View File

@@ -1,7 +1,8 @@
import { BackgroundCode, CourseNo, TitleCode } from "../model/base";
import { BackgroundCode, CourseNo, StampCode, TitleCode } from "../model/base";
import { Car } from "../model/car";
import { MissionState } from "../model/mission";
import { Settings } from "../model/settings";
import { SelectedStamps } from "../model/stamps";
import { Story } from "../model/story";
import { Tickets } from "../model/tickets";
import { Unlocks } from "../model/unlocks";
@@ -26,4 +27,6 @@ export interface SaveProfileRequest {
unlocks: Unlocks;
tickets: Tickets;
settings: Settings;
selectedStamps?: SelectedStamps;
stamps?: Set<StampCode>;
}

View File

@@ -1,8 +1,9 @@
import { TitleCode } from "../model/base";
import { StampCode, TitleCode } from "../model/base";
import { Car } from "../model/car";
import { Chara } from "../model/chara";
import { MissionState } from "../model/mission";
import { Settings } from "../model/settings";
import { SelectedStamps } from "../model/stamps";
import { Story } from "../model/story";
import { Tickets } from "../model/tickets";
import { TimeAttackScore } from "../model/timeAttack";
@@ -31,5 +32,7 @@ export interface LoadProfileResponse {
story: Story;
unlocks: Unlocks;
tickets: Tickets;
stamps: Set<StampCode>;
selectedStamps: SelectedStamps;
// giga TODO
}

View File

@@ -5,6 +5,7 @@ import { SqlCoursePlaysRepository } from "./coursePlays";
import { SqlMissionsRepository } from "./missions";
import { SqlProfileRepository } from "./profile";
import { SqlSettingsRepository } from "./settings";
import { SqlStampsRepository } from "./stamps";
import { SqlStoryRepository } from "./story";
import { SqlTeamRepository } from "./team";
import { SqlTeamAutoRepository } from "./teamAuto";
@@ -49,6 +50,10 @@ export class SqlRepositories implements Repo.Repositories {
return new SqlSettingsRepository(this._txn);
}
stamps(): Repo.StampsRepository {
return new SqlStampsRepository(this._txn);
}
story(): Repo.FacetRepository<Model.Story> {
return new SqlStoryRepository(this._txn);
}

View File

@@ -0,0 +1,97 @@
import sql from "sql-bricks-postgres";
import { StampCode } from "../model/base";
import { SelectedStamps } from "../model/stamps";
import { Profile } from "../model/profile";
import { StampsRepository } from "../repo";
import { Id } from "../../../model";
import { Transaction } from "../../../sql";
const defaultSelection: SelectedStamps = {
stamp01: 0 as StampCode,
stamp02: 0 as StampCode,
stamp03: 0 as StampCode,
stamp04: 0 as StampCode,
};
export class SqlStampsRepository implements StampsRepository {
constructor(private readonly _txn: Transaction) {}
async loadAll(id: Id<Profile>): Promise<Set<StampCode>> {
const loadSql = sql
.select("stamp.stamp_no")
.from("idz_stamp_unlock stamp")
.join("idz_profile p", { "stamp.profile_id": "p.id" })
.where("p.id", id);
const rows = await this._txn.fetchRows(loadSql);
const result = new Set<StampCode>();
for (const row of rows) {
result.add(parseInt(row.stamp_no!) as StampCode);
}
return result;
}
async loadSelection(id: Id<Profile>): Promise<SelectedStamps> {
const loadSql = sql
.select("stamp.*")
.from("idz_stamp_selection stamp")
.join("idz_profile p", { "stamp.profile_id": "p.id" })
.where("p.id", id);
const row = await this._txn.fetchRow(loadSql);
if (row === undefined) {
return { ...defaultSelection };
}
return {
stamp01: parseInt(row.stamp_01!) as StampCode,
stamp02: parseInt(row.stamp_02!) as StampCode,
stamp03: parseInt(row.stamp_03!) as StampCode,
stamp04: parseInt(row.stamp_04!) as StampCode,
};
}
async saveSelection(
profileId: Id<Profile>,
selection: SelectedStamps
): Promise<void> {
const saveSql = sql
.insert("idz_stamp_selection", {
id: this._txn.generateId(),
profile_id: profileId,
stamp_01: selection.stamp01,
stamp_02: selection.stamp02,
stamp_03: selection.stamp03,
stamp_04: selection.stamp04,
})
.onConflict("profile_id")
.doUpdate(["stamp_01", "stamp_02", "stamp_03", "stamp_04"]);
await this._txn.modify(saveSql);
}
async saveAll(profileId: Id<Profile>, flags: Set<StampCode>): Promise<void> {
const existing = await this.loadAll(profileId);
for (const flag of flags) {
if (existing.has(flag)) {
continue;
}
const saveSql = sql
.insert("idz_stamp_unlock", {
id: this._txn.generateId(),
profile_id: profileId,
stamp_no: flag,
})
.onConflict("profile_id", "stamp_no")
.doNothing();
await this._txn.modify(saveSql);
}
}
}