chunithm: Save and load user duel list

This commit is contained in:
Matt Bilker 2019-11-27 09:02:29 +00:00
parent 87de57fe2f
commit 0f2811197a
No known key found for this signature in database
GPG Key ID: 69ADF8AEB6C8B5D1
11 changed files with 156 additions and 4 deletions

View File

@ -0,0 +1,16 @@
create table "cm_user_duel_list" (
"id" integer primary key not null,
"profile_id" integer not null
references "cm_user_data"("id")
on delete cascade,
"duel_id" integer not null,
"progress" integer not null,
"point" integer not null,
"is_clear" boolean not null,
"last_play_date" text not null,
"param1" integer not null,
"param2" integer not null,
"param3" integer not null,
"param4" integer not null,
constraint "cm_user_duel_list_uq" unique ("profile_id", "duel_id")
);

View File

@ -1,14 +1,23 @@
import { Repositories } from "../repo";
import { GetUserDuelRequest } from "../request/getUserDuel";
import { GetUserDuelResponse } from "../response/getUserDuel";
import { readAimeId } from "../proto/base";
import { writeUserDuelList } from "../proto/userDuelList";
export default async function getUserDuel(
rep: Repositories,
req: GetUserDuelRequest
): Promise<GetUserDuelResponse> {
const aimeId = readAimeId(req.userId);
// Get all duel entities if the client specifies to.
const duelId = req.isAllDuel ? undefined : parseInt(req.duelId);
const profileId = await rep.userData().lookup(aimeId);
const items = await rep.userDuelList().load(profileId, duelId);
return {
userId: req.userId,
length: "0",
userDuelList: [],
length: items.length.toString(),
userDuelList: items.map(writeUserDuelList),
};
}

View File

@ -11,6 +11,7 @@ import { readUserItem } from "../proto/userItem";
import { readUserMusicDetail } from "../proto/userMusic";
import { readUserActivity } from "../proto/userActivity";
import { readUserDataEx } from "../proto/userDataEx";
import { readUserDuelList } from "../proto/userDuelList";
import { readUserPlaylog } from "../proto/userPlaylog";
// It shouldn't need to be said really, but seeing as this message (A) requires
@ -69,5 +70,9 @@ export default async function upsertUserAll(
await rep.userDataEx().save(profileId, readUserDataEx(item));
}
for (const item of payload.userDuelList || []) {
await rep.userDuelList().save(profileId, readUserDuelList(item));
}
return { returnCode: "1" };
}

View File

@ -0,0 +1,11 @@
export interface UserDuelListItem {
duelId: number;
progress: number;
point: number;
isClear: boolean;
lastPlayDate: Date;
param1: number;
param2: number;
param3: number;
param4: number;
}

View File

@ -0,0 +1,26 @@
import { Crush, readBoolean, readDate, writeObject } from "./base";
import { UserDuelListItem } from "../model/userDuelList";
export type UserDuelListJson = Crush<UserDuelListItem>;
export function readUserDuelList(
json: UserDuelListJson
): UserDuelListItem {
return {
duelId: parseInt(json.duelId),
progress: parseInt(json.progress),
point: parseInt(json.point),
isClear: readBoolean(json.isClear),
lastPlayDate: readDate(json.lastPlayDate),
param1: parseInt(json.param1),
param2: parseInt(json.param2),
param3: parseInt(json.param3),
param4: parseInt(json.param4),
};
}
export function writeUserDuelList(
obj: UserDuelListItem
): UserDuelListJson {
return writeObject(obj);
}

View File

@ -4,6 +4,7 @@ import { UserActivityRepository } from "./userActivity";
import { UserCharacterRepository } from "./userCharacter";
import { UserDataRepository } from "./userData";
import { UserDataExRepository } from "./userDataEx";
import { UserDuelListRepository } from "./userDuelList";
import { UserGameOptionRepository } from "./userGameOption";
import { UserGameOptionExRepository } from "./userGameOptionEx";
import { UserItemRepository } from "./userItem";
@ -20,6 +21,8 @@ export interface Repositories {
userDataEx(): UserDataExRepository;
userDuelList(): UserDuelListRepository;
userGameOption(): UserGameOptionRepository;
userGameOptionEx(): UserGameOptionExRepository;

View File

@ -0,0 +1,13 @@
import { Page } from "./_defs";
import { UserDataItem } from "../model/userData";
import { UserDuelListItem } from "../model/userDuelList";
import { Id } from "../../model";
export interface UserDuelListRepository {
load(
profileId: Id<UserDataItem>,
duelId?: number,
): Promise<UserDuelListItem[]>;
save(profileId: Id<UserDataItem>, obj: UserDuelListItem): Promise<void>;
}

View File

@ -9,6 +9,7 @@ import { UserActivityJson } from "../proto/userActivity";
import { UserRecentRatingJson } from "../proto/userRecentRating";
import { UserPlaylogJson } from "../proto/userPlaylog";
import { UserDataExJson } from "../proto/userDataEx";
import { UserDuelListJson } from "../proto/userDuelList";
export interface UpsertUserAllRequest {
/** Integer, AiMe ID */
@ -26,6 +27,7 @@ export interface UpsertUserAllRequest {
userRecentRatingList?: UserRecentRatingJson[];
userPlaylogList?: UserPlaylogJson[];
userDataEx?: UserDataExJson[];
userDuelList?: UserDuelListJson[];
/** String of binary digits */
isNewMapList: string;

View File

@ -1,3 +1,5 @@
import { UserDuelListJson } from "../proto/userDuelList";
export interface GetUserDuelResponse {
/** Integer, AiMe ID */
userId: string;
@ -5,6 +7,9 @@ export interface GetUserDuelResponse {
/** Integer, number of results returned */
length: string;
/** TBD */
userDuelList: [];
/**
* List of duel entities, either all duel entities associated with `userId`
* or single requested by `duelId` in request.
*/
userDuelList: UserDuelListJson[];
}

View File

@ -2,6 +2,7 @@ import { SqlUserActivityRepository } from "./userActivity";
import { SqlUserCharacterRepository } from "./userCharacter";
import { SqlUserDataRepository } from "./userData";
import { SqlUserDataExRepository } from "./userDataEx";
import { SqlUserDuelListRepository } from "./userDuelList";
import { SqlUserGameOptionRepository } from "./userGameOption";
import { SqlUserGameOptionExRepository } from "./userGameOptionEx";
import { SqlUserItemRepository } from "./userItem";
@ -13,6 +14,7 @@ import { UserActivityRepository } from "../repo/userActivity";
import { UserCharacterRepository } from "../repo/userCharacter";
import { UserDataRepository } from "../repo/userData";
import { UserDataExRepository } from "../repo/userDataEx";
import { UserDuelListRepository } from "../repo/userDuelList";
import { UserGameOptionRepository } from "../repo/userGameOption";
import { UserGameOptionExRepository } from "../repo/userGameOptionEx";
import { UserItemRepository } from "../repo/userItem";
@ -40,6 +42,10 @@ export class SqlRepositories implements Repositories {
return new SqlUserDataExRepository(this._txn);
}
userDuelList(): UserDuelListRepository {
return new SqlUserDuelListRepository(this._txn);
}
userGameOption(): UserGameOptionRepository {
return new SqlUserGameOptionRepository(this._txn);
}

View File

@ -0,0 +1,56 @@
import sql from "sql-bricks-postgres";
import { UserDataItem } from "../model/userData";
import { UserDuelListItem } from "../model/userDuelList";
import { Page } from "../repo";
import { UserDuelListRepository } from "../repo/userDuelList";
import { Id } from "../../model";
import { Transaction } from "../../sql";
import { T, createSqlMapper } from "../../sql/util";
const { readRow, writeRow, colNames } = createSqlMapper({
duelId: T.number,
progress: T.number,
point: T.number,
isClear: T.boolean,
lastPlayDate: T.Date,
param1: T.number,
param2: T.number,
param3: T.number,
param4: T.number,
});
export class SqlUserDuelListRepository implements UserDuelListRepository {
constructor(private readonly _txn: Transaction) {}
async load(
profileId: Id<UserDataItem>,
duelId?: number
): Promise<UserDuelListItem[]> {
const stmt = sql
.select("*")
.from("cm_user_duel_list")
.where("profile_id", profileId);
if (duelId !== undefined) {
stmt.where("duel_id", duelId);
}
const rows = await this._txn.fetchRows(stmt);
return rows.map(readRow);
}
save(profileId: Id<UserDataItem>, obj: UserDuelListItem): Promise<void> {
const stmt = sql
.insert("cm_user_duel_list", {
id: this._txn.generateId(),
profile_id: profileId,
...writeRow(obj),
})
.onConflict("profile_id", "duel_id")
.doUpdate(colNames);
return this._txn.modify(stmt);
}
}